diff options
author | erdgeist <erdgeist@erdgeist.org> | 2025-08-15 12:42:40 +0200 |
---|---|---|
committer | erdgeist <erdgeist@erdgeist.org> | 2025-08-15 12:42:40 +0200 |
commit | 30325d24d107dbf133da39f7c96d1510fd1c9449 (patch) | |
tree | 932baa5b2a4475821f16dccf9e3e05011daa6d92 | |
parent | 9022d768021bbe15c7815cc6f8b64218b46f0e10 (diff) |
Bump to codec2 version 1.2.0erdgeist-bump-to-1.2.0
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | _kiss_fft_guts.h | 234 | ||||
-rw-r--r-- | bpf.h | 120 | ||||
-rw-r--r-- | bpfb.h | 119 | ||||
-rw-r--r-- | codebook.c | 82 | ||||
-rw-r--r-- | codebookd.c | 82 | ||||
-rw-r--r-- | codebookge.c | 10 | ||||
-rw-r--r-- | codebookjmv.c (renamed from codebookjvm.c) | 28 | ||||
-rw-r--r-- | codebooklspmelvq.c | 247 | ||||
-rw-r--r-- | codebookmel.c | 145 | ||||
-rw-r--r-- | codebooknewamp1.c | 16 | ||||
-rw-r--r-- | codebooknewamp1_energy.c | 8 | ||||
-rw-r--r-- | codebooknewamp2.c | 2 | ||||
-rw-r--r-- | codec2.c | 3331 | ||||
-rw-r--r-- | codec2.h | 102 | ||||
-rw-r--r-- | codec2_fft.c | 112 | ||||
-rw-r--r-- | codec2_fft.h | 111 | ||||
-rw-r--r-- | codec2_internal.h | 129 | ||||
-rw-r--r-- | comp_prim.h | 109 | ||||
-rw-r--r-- | defines.h | 89 | ||||
-rw-r--r-- | interp.c | 247 | ||||
-rw-r--r-- | interp.h | 16 | ||||
-rw-r--r-- | kiss_fft.c | 714 | ||||
-rw-r--r-- | kiss_fft.h | 60 | ||||
-rw-r--r-- | kiss_fftr.c | 272 | ||||
-rw-r--r-- | kiss_fftr.h | 25 | ||||
-rw-r--r-- | lpc.c | 223 | ||||
-rw-r--r-- | lpc.h | 8 | ||||
-rw-r--r-- | lsp.c | 354 | ||||
-rw-r--r-- | lsp.h | 2 | ||||
-rw-r--r-- | machdep.h | 12 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | mbest.c | 194 | ||||
-rw-r--r-- | mbest.h | 23 | ||||
-rw-r--r-- | newamp1.c | 770 | ||||
-rw-r--r-- | newamp1.h | 86 | ||||
-rw-r--r-- | newamp2.c | 570 | ||||
-rw-r--r-- | newamp2.h | 89 | ||||
-rw-r--r-- | nlp.c | 609 | ||||
-rw-r--r-- | nlp.h | 5 | ||||
-rw-r--r-- | os.h | 82 | ||||
-rw-r--r-- | pack.c | 104 | ||||
-rw-r--r-- | phase.c | 242 | ||||
-rw-r--r-- | phase.h | 6 | ||||
-rw-r--r-- | postfilter.c | 58 | ||||
-rw-r--r-- | postfilter.h | 2 | ||||
-rw-r--r-- | quantise.c | 1992 | ||||
-rw-r--r-- | quantise.h | 116 | ||||
-rw-r--r-- | sine.c | 591 | ||||
-rw-r--r-- | sine.h | 13 | ||||
-rwxr-xr-x | stripdown.sh | 17 | ||||
-rw-r--r-- | version.h | 8 |
52 files changed, 4804 insertions, 7793 deletions
@@ -1,11 +1,10 @@ | |||
1 | CFLAGS = -Wall -Wno-strict-overflow -std=gnu11 -fPIC -g -O2 -I. | 1 | CFLAGS = -Wall -Wno-strict-overflow -std=gnu11 -fPIC -g -O2 -I. -lm |
2 | CFLAGS += -DHORUS_L2_RX -DINTERLEAVER -DRUN_TIME_TABLES -DSCRAMBLER -Dcodec2_EXPORTS | 2 | CFLAGS += -DHORUS_L2_RX -DINTERLEAVER -DRUN_TIME_TABLES -DSCRAMBLER -Dcodec2_EXPORTS |
3 | CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers | 3 | CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers |
4 | 4 | ||
5 | LIBSRC=codebook.c codebookd.c codebookge.c codebookmel.c codebooklspmelvq.c codebookjvm.c \ | 5 | LIBSRC=codebook.c codebookd.c codebookge.c codebookjmv.c codebooknewamp1_energy.c \ |
6 | codebooknewamp1.c codebooknewamp1_energy.c codebooknewamp2.c codebooknewamp2_energy.c \ | 6 | codebooknewamp1.c codec2.c codec2_fft.c interp.c kiss_fft.c kiss_fftr.c \ |
7 | codec2.c codec2_fft.c interp.c kiss_fft.c kiss_fftr.c lpc.c lsp.c mbest.c \ | 7 | lpc.c lsp.c mbest.c newamp1.c nlp.c pack.c phase.c postfilter.c quantise.c sine.c |
8 | newamp1.c newamp2.c nlp.c pack.c phase.c postfilter.c quantise.c sine.c | ||
9 | 8 | ||
10 | all: main | 9 | all: main |
11 | 10 | ||
diff --git a/_kiss_fft_guts.h b/_kiss_fft_guts.h index 1c62a34..16305af 100644 --- a/_kiss_fft_guts.h +++ b/_kiss_fft_guts.h | |||
@@ -3,33 +3,49 @@ Copyright (c) 2003-2010, Mark Borgerding | |||
3 | 3 | ||
4 | All rights reserved. | 4 | All rights reserved. |
5 | 5 | ||
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | 6 | Redistribution and use in source and binary forms, with or without modification, |
7 | 7 | are permitted provided that the following conditions are met: | |
8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | 8 | |
9 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | 9 | * Redistributions of source code must retain the above copyright notice, |
10 | * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. | 10 | this list of conditions and the following disclaimer. |
11 | 11 | * Redistributions in binary form must reproduce the above copyright notice, | |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 12 | this list of conditions and the following disclaimer in the documentation and/or |
13 | other materials provided with the distribution. | ||
14 | * Neither the author nor the names of any contributors may be used to | ||
15 | endorse or promote products derived from this software without specific prior | ||
16 | written permission. | ||
17 | |||
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
13 | */ | 28 | */ |
14 | 29 | ||
15 | /* kiss_fft.h | 30 | /* kiss_fft.h |
16 | defines kiss_fft_scalar as either short or a float type | 31 | defines kiss_fft_scalar as either short or a float type |
17 | and defines | 32 | and defines |
18 | typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ | 33 | typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ |
19 | #include "kiss_fft.h" | ||
20 | #include <limits.h> | 34 | #include <limits.h> |
21 | 35 | ||
36 | #include "kiss_fft.h" | ||
37 | |||
22 | #define MAXFACTORS 32 | 38 | #define MAXFACTORS 32 |
23 | /* e.g. an fft of length 128 has 4 factors | 39 | /* e.g. an fft of length 128 has 4 factors |
24 | as far as kissfft is concerned | 40 | as far as kissfft is concerned |
25 | 4*4*4*2 | 41 | 4*4*4*2 |
26 | */ | 42 | */ |
27 | 43 | ||
28 | struct kiss_fft_state{ | 44 | struct kiss_fft_state { |
29 | int nfft; | 45 | int nfft; |
30 | int inverse; | 46 | int inverse; |
31 | int factors[2*MAXFACTORS]; | 47 | int factors[2 * MAXFACTORS]; |
32 | kiss_fft_cpx twiddles[1]; | 48 | kiss_fft_cpx twiddles[1]; |
33 | }; | 49 | }; |
34 | 50 | ||
35 | /* | 51 | /* |
@@ -42,123 +58,137 @@ struct kiss_fft_state{ | |||
42 | C_ADDTO( res , a) : res += a | 58 | C_ADDTO( res , a) : res += a |
43 | * */ | 59 | * */ |
44 | #ifdef FIXED_POINT | 60 | #ifdef FIXED_POINT |
45 | #if (FIXED_POINT==32) | 61 | #if (FIXED_POINT == 32) |
46 | # define FRACBITS 31 | 62 | #define FRACBITS 31 |
47 | # define SAMPPROD int64_t | 63 | #define SAMPPROD int64_t |
48 | #define SAMP_MAX 2147483647 | 64 | #define SAMP_MAX 2147483647 |
49 | #else | 65 | #else |
50 | # define FRACBITS 15 | 66 | #define FRACBITS 15 |
51 | # define SAMPPROD int32_t | 67 | #define SAMPPROD int32_t |
52 | #define SAMP_MAX 32767 | 68 | #define SAMP_MAX 32767 |
53 | #endif | 69 | #endif |
54 | 70 | ||
55 | #define SAMP_MIN -SAMP_MAX | 71 | #define SAMP_MIN -SAMP_MAX |
56 | 72 | ||
57 | #if defined(CHECK_OVERFLOW) | 73 | #if defined(CHECK_OVERFLOW) |
58 | # define CHECK_OVERFLOW_OP(a,op,b) \ | 74 | #define CHECK_OVERFLOW_OP(a, op, b) \ |
59 | if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ | 75 | if ((SAMPPROD)(a)op(SAMPPROD)(b) > SAMP_MAX || \ |
60 | fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } | 76 | (SAMPPROD)(a)op(SAMPPROD)(b) < SAMP_MIN) { \ |
77 | fprintf(stderr, \ | ||
78 | "WARNING:overflow @ " __FILE__ "(%d): (%d " #op " %d) = %ld\n", \ | ||
79 | __LINE__, (a), (b), (SAMPPROD)(a)op(SAMPPROD)(b)); \ | ||
80 | } | ||
61 | #endif | 81 | #endif |
62 | 82 | ||
63 | 83 | #define smul(a, b) ((SAMPPROD)(a) * (b)) | |
64 | # define smul(a,b) ( (SAMPPROD)(a)*(b) ) | 84 | #define sround(x) (kiss_fft_scalar)(((x) + (1 << (FRACBITS - 1))) >> FRACBITS) |
65 | # define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) | 85 | |
66 | 86 | #define S_MUL(a, b) sround(smul(a, b)) | |
67 | # define S_MUL(a,b) sround( smul(a,b) ) | 87 | |
68 | 88 | #define C_MUL(m, a, b) \ | |
69 | # define C_MUL(m,a,b) \ | 89 | do { \ |
70 | do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ | 90 | (m).r = sround(smul((a).r, (b).r) - smul((a).i, (b).i)); \ |
71 | (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) | 91 | (m).i = sround(smul((a).r, (b).i) + smul((a).i, (b).r)); \ |
72 | 92 | } while (0) | |
73 | # define DIVSCALAR(x,k) \ | 93 | |
74 | (x) = sround( smul( x, SAMP_MAX/k ) ) | 94 | #define DIVSCALAR(x, k) (x) = sround(smul(x, SAMP_MAX / k)) |
75 | 95 | ||
76 | # define C_FIXDIV(c,div) \ | 96 | #define C_FIXDIV(c, div) \ |
77 | do { DIVSCALAR( (c).r , div); \ | 97 | do { \ |
78 | DIVSCALAR( (c).i , div); }while (0) | 98 | DIVSCALAR((c).r, div); \ |
79 | 99 | DIVSCALAR((c).i, div); \ | |
80 | # define C_MULBYSCALAR( c, s ) \ | 100 | } while (0) |
81 | do{ (c).r = sround( smul( (c).r , s ) ) ;\ | 101 | |
82 | (c).i = sround( smul( (c).i , s ) ) ; }while(0) | 102 | #define C_MULBYSCALAR(c, s) \ |
83 | 103 | do { \ | |
84 | #else /* not FIXED_POINT*/ | 104 | (c).r = sround(smul((c).r, s)); \ |
85 | 105 | (c).i = sround(smul((c).i, s)); \ | |
86 | # define S_MUL(a,b) ( (a)*(b) ) | 106 | } while (0) |
87 | #define C_MUL(m,a,b) \ | 107 | |
88 | do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ | 108 | #else /* not FIXED_POINT*/ |
89 | (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) | 109 | |
90 | # define C_FIXDIV(c,div) /* NOOP */ | 110 | #define S_MUL(a, b) ((a) * (b)) |
91 | # define C_MULBYSCALAR( c, s ) \ | 111 | #define C_MUL(m, a, b) \ |
92 | do{ (c).r *= (s);\ | 112 | do { \ |
93 | (c).i *= (s); }while(0) | 113 | (m).r = (a).r * (b).r - (a).i * (b).i; \ |
114 | (m).i = (a).r * (b).i + (a).i * (b).r; \ | ||
115 | } while (0) | ||
116 | #define C_FIXDIV(c, div) /* NOOP */ | ||
117 | #define C_MULBYSCALAR(c, s) \ | ||
118 | do { \ | ||
119 | (c).r *= (s); \ | ||
120 | (c).i *= (s); \ | ||
121 | } while (0) | ||
94 | #endif | 122 | #endif |
95 | 123 | ||
96 | #ifndef CHECK_OVERFLOW_OP | 124 | #ifndef CHECK_OVERFLOW_OP |
97 | # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ | 125 | #define CHECK_OVERFLOW_OP(a, op, b) /* noop */ |
98 | #endif | 126 | #endif |
99 | 127 | ||
100 | #define C_ADD( res, a,b)\ | 128 | #define C_ADD(res, a, b) \ |
101 | do { \ | 129 | do { \ |
102 | CHECK_OVERFLOW_OP((a).r,+,(b).r)\ | 130 | CHECK_OVERFLOW_OP((a).r, +, (b).r) \ |
103 | CHECK_OVERFLOW_OP((a).i,+,(b).i)\ | 131 | CHECK_OVERFLOW_OP((a).i, +, (b).i) \ |
104 | (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ | 132 | (res).r = (a).r + (b).r; \ |
105 | }while(0) | 133 | (res).i = (a).i + (b).i; \ |
106 | #define C_SUB( res, a,b)\ | 134 | } while (0) |
107 | do { \ | 135 | #define C_SUB(res, a, b) \ |
108 | CHECK_OVERFLOW_OP((a).r,-,(b).r)\ | 136 | do { \ |
109 | CHECK_OVERFLOW_OP((a).i,-,(b).i)\ | 137 | CHECK_OVERFLOW_OP((a).r, -, (b).r) \ |
110 | (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ | 138 | CHECK_OVERFLOW_OP((a).i, -, (b).i) \ |
111 | }while(0) | 139 | (res).r = (a).r - (b).r; \ |
112 | #define C_ADDTO( res , a)\ | 140 | (res).i = (a).i - (b).i; \ |
113 | do { \ | 141 | } while (0) |
114 | CHECK_OVERFLOW_OP((res).r,+,(a).r)\ | 142 | #define C_ADDTO(res, a) \ |
115 | CHECK_OVERFLOW_OP((res).i,+,(a).i)\ | 143 | do { \ |
116 | (res).r += (a).r; (res).i += (a).i;\ | 144 | CHECK_OVERFLOW_OP((res).r, +, (a).r) \ |
117 | }while(0) | 145 | CHECK_OVERFLOW_OP((res).i, +, (a).i) \ |
118 | 146 | (res).r += (a).r; \ | |
119 | #define C_SUBFROM( res , a)\ | 147 | (res).i += (a).i; \ |
120 | do {\ | 148 | } while (0) |
121 | CHECK_OVERFLOW_OP((res).r,-,(a).r)\ | 149 | |
122 | CHECK_OVERFLOW_OP((res).i,-,(a).i)\ | 150 | #define C_SUBFROM(res, a) \ |
123 | (res).r -= (a).r; (res).i -= (a).i; \ | 151 | do { \ |
124 | }while(0) | 152 | CHECK_OVERFLOW_OP((res).r, -, (a).r) \ |
125 | 153 | CHECK_OVERFLOW_OP((res).i, -, (a).i) \ | |
154 | (res).r -= (a).r; \ | ||
155 | (res).i -= (a).i; \ | ||
156 | } while (0) | ||
126 | 157 | ||
127 | #ifdef FIXED_POINT | 158 | #ifdef FIXED_POINT |
128 | # define KISS_FFT_COS(phase) floorf(.5+SAMP_MAX * cosf (phase)) | 159 | #define KISS_FFT_COS(phase) floorf(.5 + SAMP_MAX * cosf(phase)) |
129 | # define KISS_FFT_SIN(phase) floorf(.5+SAMP_MAX * sinf (phase)) | 160 | #define KISS_FFT_SIN(phase) floorf(.5 + SAMP_MAX * sinf(phase)) |
130 | # define HALF_OF(x) ((x)>>1) | 161 | #define HALF_OF(x) ((x) >> 1) |
131 | #elif defined(USE_SIMD) | 162 | #elif defined(USE_SIMD) |
132 | # define KISS_FFT_COS(phase) _mm_set1_ps( cosf(phase) ) | 163 | #define KISS_FFT_COS(phase) _mm_set1_ps(cosf(phase)) |
133 | # define KISS_FFT_SIN(phase) _mm_set1_ps( sinf(phase) ) | 164 | #define KISS_FFT_SIN(phase) _mm_set1_ps(sinf(phase)) |
134 | # define HALF_OF(x) ((x)*_mm_set1_ps(.5)) | 165 | #define HALF_OF(x) ((x)*_mm_set1_ps(.5)) |
135 | #else | 166 | #else |
136 | # define KISS_FFT_COS(phase) (kiss_fft_scalar) cosf(phase) | 167 | #define KISS_FFT_COS(phase) (kiss_fft_scalar) cosf(phase) |
137 | # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sinf(phase) | 168 | #define KISS_FFT_SIN(phase) (kiss_fft_scalar) sinf(phase) |
138 | # define HALF_OF(x) ((x)*.5) | 169 | #define HALF_OF(x) ((x)*.5) |
139 | #endif | 170 | #endif |
140 | 171 | ||
141 | #define kf_cexp(x,phase) \ | 172 | #define kf_cexp(x, phase) \ |
142 | do{ \ | 173 | do { \ |
143 | (x)->r = KISS_FFT_COS(phase);\ | 174 | (x)->r = KISS_FFT_COS(phase); \ |
144 | (x)->i = KISS_FFT_SIN(phase);\ | 175 | (x)->i = KISS_FFT_SIN(phase); \ |
145 | }while(0) | 176 | } while (0) |
146 | |||
147 | 177 | ||
148 | /* a debugging function */ | 178 | /* a debugging function */ |
149 | #define pcpx(c)\ | 179 | #define pcpx(c) \ |
150 | fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) | 180 | fprintf(stderr, "%g + %gi\n", (double)((c)->r), (double)((c)->i)) |
151 | |||
152 | 181 | ||
153 | #ifdef KISS_FFT_USE_ALLOCA | 182 | #ifdef KISS_FFT_USE_ALLOCA |
154 | // define this to allow use of alloca instead of malloc for temporary buffers | 183 | // define this to allow use of alloca instead of malloc for temporary buffers |
155 | // Temporary buffers are used in two case: | 184 | // Temporary buffers are used in two case: |
156 | // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 | 185 | // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 |
157 | // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. | 186 | // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an |
187 | // in-place transform. | ||
158 | #include <alloca.h> | 188 | #include <alloca.h> |
159 | #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) | 189 | #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) |
160 | #define KISS_FFT_TMP_FREE(ptr) | 190 | #define KISS_FFT_TMP_FREE(ptr) |
161 | #else | 191 | #else |
162 | #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) | 192 | #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) |
163 | #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) | 193 | #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) |
164 | #endif | 194 | #endif |
@@ -1,106 +1,18 @@ | |||
1 | #define BPF_N 101 | 1 | #define BPF_N 101 |
2 | 2 | ||
3 | float bpf[]={ | 3 | float bpf[] = { |
4 | 0.002174, | 4 | 0.002174, 0.003245, 0.002147, 0.001866, 0.002764, 0.000567, -0.001641, |
5 | 0.003245, | 5 | -0.000565, -0.002415, -0.005837, -0.003620, -0.002828, -0.006268, -0.002787, |
6 | 0.002147, | 6 | 0.001963, -0.001234, 0.001446, 0.009200, 0.005331, 0.003521, 0.011821, |
7 | 0.001866, | 7 | 0.006951, -0.002015, 0.005137, 0.001828, -0.013390, -0.007058, -0.003273, |
8 | 0.002764, | 8 | -0.020458, -0.014321, 0.001751, -0.012891, -0.009730, 0.018993, 0.008544, |
9 | 0.000567, | 9 | 0.000534, 0.035755, 0.029074, -0.001192, 0.030852, 0.030983, -0.029834, |
10 | -0.001641, | 10 | -0.009550, 0.011945, -0.081971, -0.082875, 0.000423, -0.133526, -0.211778, |
11 | -0.000565, | 11 | 0.182628, 0.514906, 0.182628, -0.211778, -0.133526, 0.000423, -0.082875, |
12 | -0.002415, | 12 | -0.081971, 0.011945, -0.009550, -0.029834, 0.030983, 0.030852, -0.001192, |
13 | -0.005837, | 13 | 0.029074, 0.035755, 0.000534, 0.008544, 0.018993, -0.009730, -0.012891, |
14 | -0.003620, | 14 | 0.001751, -0.014321, -0.020458, -0.003273, -0.007058, -0.013390, 0.001828, |
15 | -0.002828, | 15 | 0.005137, -0.002015, 0.006951, 0.011821, 0.003521, 0.005331, 0.009200, |
16 | -0.006268, | 16 | 0.001446, -0.001234, 0.001963, -0.002787, -0.006268, -0.002828, -0.003620, |
17 | -0.002787, | 17 | -0.005837, -0.002415, -0.000565, -0.001641, 0.000567, 0.002764, 0.001866, |
18 | 0.001963, | 18 | 0.002147, 0.003245, 0.002174}; |
19 | -0.001234, | ||
20 | 0.001446, | ||
21 | 0.009200, | ||
22 | 0.005331, | ||
23 | 0.003521, | ||
24 | 0.011821, | ||
25 | 0.006951, | ||
26 | -0.002015, | ||
27 | 0.005137, | ||
28 | 0.001828, | ||
29 | -0.013390, | ||
30 | -0.007058, | ||
31 | -0.003273, | ||
32 | -0.020458, | ||
33 | -0.014321, | ||
34 | 0.001751, | ||
35 | -0.012891, | ||
36 | -0.009730, | ||
37 | 0.018993, | ||
38 | 0.008544, | ||
39 | 0.000534, | ||
40 | 0.035755, | ||
41 | 0.029074, | ||
42 | -0.001192, | ||
43 | 0.030852, | ||
44 | 0.030983, | ||
45 | -0.029834, | ||
46 | -0.009550, | ||
47 | 0.011945, | ||
48 | -0.081971, | ||
49 | -0.082875, | ||
50 | 0.000423, | ||
51 | -0.133526, | ||
52 | -0.211778, | ||
53 | 0.182628, | ||
54 | 0.514906, | ||
55 | 0.182628, | ||
56 | -0.211778, | ||
57 | -0.133526, | ||
58 | 0.000423, | ||
59 | -0.082875, | ||
60 | -0.081971, | ||
61 | 0.011945, | ||
62 | -0.009550, | ||
63 | -0.029834, | ||
64 | 0.030983, | ||
65 | 0.030852, | ||
66 | -0.001192, | ||
67 | 0.029074, | ||
68 | 0.035755, | ||
69 | 0.000534, | ||
70 | 0.008544, | ||
71 | 0.018993, | ||
72 | -0.009730, | ||
73 | -0.012891, | ||
74 | 0.001751, | ||
75 | -0.014321, | ||
76 | -0.020458, | ||
77 | -0.003273, | ||
78 | -0.007058, | ||
79 | -0.013390, | ||
80 | 0.001828, | ||
81 | 0.005137, | ||
82 | -0.002015, | ||
83 | 0.006951, | ||
84 | 0.011821, | ||
85 | 0.003521, | ||
86 | 0.005331, | ||
87 | 0.009200, | ||
88 | 0.001446, | ||
89 | -0.001234, | ||
90 | 0.001963, | ||
91 | -0.002787, | ||
92 | -0.006268, | ||
93 | -0.002828, | ||
94 | -0.003620, | ||
95 | -0.005837, | ||
96 | -0.002415, | ||
97 | -0.000565, | ||
98 | -0.001641, | ||
99 | 0.000567, | ||
100 | 0.002764, | ||
101 | 0.001866, | ||
102 | 0.002147, | ||
103 | 0.003245, | ||
104 | 0.002174 | ||
105 | }; | ||
106 | |||
@@ -1,105 +1,18 @@ | |||
1 | #define BPFB_N 101 | 1 | #define BPFB_N 101 |
2 | 2 | ||
3 | float bpfb[]={ | 3 | float bpfb[] = { |
4 | 0.003795, | 4 | 0.003795, 0.006827, 0.002261, 0.002523, 0.005758, -0.000264, -0.000674, |
5 | 0.006827, | 5 | 0.003113, -0.004144, -0.004923, 0.000043, -0.008017, -0.008711, -0.001802, |
6 | 0.002261, | 6 | -0.010210, -0.010428, -0.000899, -0.009413, -0.009072, 0.003469, -0.005335, |
7 | 0.002523, | 7 | -0.004828, 0.010724, 0.000941, 0.000708, 0.018957, 0.007084, 0.004825, |
8 | 0.005758, | 8 | 0.025418, 0.010147, 0.004452, 0.027434, 0.007550, -0.002861, 0.023483, |
9 | -0.000264, | 9 | -0.001944, -0.018138, 0.014122, -0.017583, -0.040768, 0.002598, -0.036604, |
10 | -0.000674, | 10 | -0.069541, -0.004273, -0.054876, -0.107289, 0.010068, -0.068052, -0.200119, |
11 | 0.003113, | 11 | 0.207287, 0.597150, 0.207287, -0.200119, -0.068052, 0.010068, -0.107289, |
12 | -0.004144, | 12 | -0.054876, -0.004273, -0.069541, -0.036604, 0.002598, -0.040768, -0.017583, |
13 | -0.004923, | 13 | 0.014122, -0.018138, -0.001944, 0.023483, -0.002861, 0.007550, 0.027434, |
14 | 0.000043, | 14 | 0.004452, 0.010147, 0.025418, 0.004825, 0.007084, 0.018957, 0.000708, |
15 | -0.008017, | 15 | 0.000941, 0.010724, -0.004828, -0.005335, 0.003469, -0.009072, -0.009413, |
16 | -0.008711, | 16 | -0.000899, -0.010428, -0.010210, -0.001802, -0.008711, -0.008017, 0.000043, |
17 | -0.001802, | 17 | -0.004923, -0.004144, 0.003113, -0.000674, -0.000264, 0.005758, 0.002523, |
18 | -0.010210, | 18 | 0.002261, 0.006827, 0.003795}; \ No newline at end of file |
19 | -0.010428, | ||
20 | -0.000899, | ||
21 | -0.009413, | ||
22 | -0.009072, | ||
23 | 0.003469, | ||
24 | -0.005335, | ||
25 | -0.004828, | ||
26 | 0.010724, | ||
27 | 0.000941, | ||
28 | 0.000708, | ||
29 | 0.018957, | ||
30 | 0.007084, | ||
31 | 0.004825, | ||
32 | 0.025418, | ||
33 | 0.010147, | ||
34 | 0.004452, | ||
35 | 0.027434, | ||
36 | 0.007550, | ||
37 | -0.002861, | ||
38 | 0.023483, | ||
39 | -0.001944, | ||
40 | -0.018138, | ||
41 | 0.014122, | ||
42 | -0.017583, | ||
43 | -0.040768, | ||
44 | 0.002598, | ||
45 | -0.036604, | ||
46 | -0.069541, | ||
47 | -0.004273, | ||
48 | -0.054876, | ||
49 | -0.107289, | ||
50 | 0.010068, | ||
51 | -0.068052, | ||
52 | -0.200119, | ||
53 | 0.207287, | ||
54 | 0.597150, | ||
55 | 0.207287, | ||
56 | -0.200119, | ||
57 | -0.068052, | ||
58 | 0.010068, | ||
59 | -0.107289, | ||
60 | -0.054876, | ||
61 | -0.004273, | ||
62 | -0.069541, | ||
63 | -0.036604, | ||
64 | 0.002598, | ||
65 | -0.040768, | ||
66 | -0.017583, | ||
67 | 0.014122, | ||
68 | -0.018138, | ||
69 | -0.001944, | ||
70 | 0.023483, | ||
71 | -0.002861, | ||
72 | 0.007550, | ||
73 | 0.027434, | ||
74 | 0.004452, | ||
75 | 0.010147, | ||
76 | 0.025418, | ||
77 | 0.004825, | ||
78 | 0.007084, | ||
79 | 0.018957, | ||
80 | 0.000708, | ||
81 | 0.000941, | ||
82 | 0.010724, | ||
83 | -0.004828, | ||
84 | -0.005335, | ||
85 | 0.003469, | ||
86 | -0.009072, | ||
87 | -0.009413, | ||
88 | -0.000899, | ||
89 | -0.010428, | ||
90 | -0.010210, | ||
91 | -0.001802, | ||
92 | -0.008711, | ||
93 | -0.008017, | ||
94 | 0.000043, | ||
95 | -0.004923, | ||
96 | -0.004144, | ||
97 | 0.003113, | ||
98 | -0.000674, | ||
99 | -0.000264, | ||
100 | 0.005758, | ||
101 | 0.002523, | ||
102 | 0.002261, | ||
103 | 0.006827, | ||
104 | 0.003795 | ||
105 | }; \ No newline at end of file | ||
@@ -1,14 +1,18 @@ | |||
1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ | 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * This intermediary file and the files that used to create it are under | 4 | * This intermediary file and the files that used to create it are under |
5 | * The LGPL. See the file COPYING. | 5 | * The LGPL. See the file COPYING. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "defines.h" | 8 | #include "defines.h" |
9 | 9 | ||
10 | /* codebook/lsp1.txt */ | 10 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp1.txt */ |
11 | #ifdef __EMBEDDED__ | ||
11 | static const float codes0[] = { | 12 | static const float codes0[] = { |
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
12 | 225, | 16 | 225, |
13 | 250, | 17 | 250, |
14 | 275, | 18 | 275, |
@@ -26,8 +30,12 @@ static const float codes0[] = { | |||
26 | 575, | 30 | 575, |
27 | 600 | 31 | 600 |
28 | }; | 32 | }; |
29 | /* codebook/lsp2.txt */ | 33 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp2.txt */ |
34 | #ifdef __EMBEDDED__ | ||
30 | static const float codes1[] = { | 35 | static const float codes1[] = { |
36 | #else | ||
37 | static float codes1[] = { | ||
38 | #endif | ||
31 | 325, | 39 | 325, |
32 | 350, | 40 | 350, |
33 | 375, | 41 | 375, |
@@ -45,8 +53,12 @@ static const float codes1[] = { | |||
45 | 675, | 53 | 675, |
46 | 700 | 54 | 700 |
47 | }; | 55 | }; |
48 | /* codebook/lsp3.txt */ | 56 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp3.txt */ |
57 | #ifdef __EMBEDDED__ | ||
49 | static const float codes2[] = { | 58 | static const float codes2[] = { |
59 | #else | ||
60 | static float codes2[] = { | ||
61 | #endif | ||
50 | 500, | 62 | 500, |
51 | 550, | 63 | 550, |
52 | 600, | 64 | 600, |
@@ -64,8 +76,12 @@ static const float codes2[] = { | |||
64 | 1200, | 76 | 1200, |
65 | 1250 | 77 | 1250 |
66 | }; | 78 | }; |
67 | /* codebook/lsp4.txt */ | 79 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp4.txt */ |
80 | #ifdef __EMBEDDED__ | ||
68 | static const float codes3[] = { | 81 | static const float codes3[] = { |
82 | #else | ||
83 | static float codes3[] = { | ||
84 | #endif | ||
69 | 700, | 85 | 700, |
70 | 800, | 86 | 800, |
71 | 900, | 87 | 900, |
@@ -83,8 +99,12 @@ static const float codes3[] = { | |||
83 | 2100, | 99 | 2100, |
84 | 2200 | 100 | 2200 |
85 | }; | 101 | }; |
86 | /* codebook/lsp5.txt */ | 102 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp5.txt */ |
103 | #ifdef __EMBEDDED__ | ||
87 | static const float codes4[] = { | 104 | static const float codes4[] = { |
105 | #else | ||
106 | static float codes4[] = { | ||
107 | #endif | ||
88 | 950, | 108 | 950, |
89 | 1050, | 109 | 1050, |
90 | 1150, | 110 | 1150, |
@@ -102,8 +122,12 @@ static const float codes4[] = { | |||
102 | 2350, | 122 | 2350, |
103 | 2450 | 123 | 2450 |
104 | }; | 124 | }; |
105 | /* codebook/lsp6.txt */ | 125 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp6.txt */ |
126 | #ifdef __EMBEDDED__ | ||
106 | static const float codes5[] = { | 127 | static const float codes5[] = { |
128 | #else | ||
129 | static float codes5[] = { | ||
130 | #endif | ||
107 | 1100, | 131 | 1100, |
108 | 1200, | 132 | 1200, |
109 | 1300, | 133 | 1300, |
@@ -121,8 +145,12 @@ static const float codes5[] = { | |||
121 | 2500, | 145 | 2500, |
122 | 2600 | 146 | 2600 |
123 | }; | 147 | }; |
124 | /* codebook/lsp7.txt */ | 148 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp7.txt */ |
149 | #ifdef __EMBEDDED__ | ||
125 | static const float codes6[] = { | 150 | static const float codes6[] = { |
151 | #else | ||
152 | static float codes6[] = { | ||
153 | #endif | ||
126 | 1500, | 154 | 1500, |
127 | 1600, | 155 | 1600, |
128 | 1700, | 156 | 1700, |
@@ -140,8 +168,12 @@ static const float codes6[] = { | |||
140 | 2900, | 168 | 2900, |
141 | 3000 | 169 | 3000 |
142 | }; | 170 | }; |
143 | /* codebook/lsp8.txt */ | 171 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp8.txt */ |
172 | #ifdef __EMBEDDED__ | ||
144 | static const float codes7[] = { | 173 | static const float codes7[] = { |
174 | #else | ||
175 | static float codes7[] = { | ||
176 | #endif | ||
145 | 2300, | 177 | 2300, |
146 | 2400, | 178 | 2400, |
147 | 2500, | 179 | 2500, |
@@ -151,8 +183,12 @@ static const float codes7[] = { | |||
151 | 2900, | 183 | 2900, |
152 | 3000 | 184 | 3000 |
153 | }; | 185 | }; |
154 | /* codebook/lsp9.txt */ | 186 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp9.txt */ |
187 | #ifdef __EMBEDDED__ | ||
155 | static const float codes8[] = { | 188 | static const float codes8[] = { |
189 | #else | ||
190 | static float codes8[] = { | ||
191 | #endif | ||
156 | 2500, | 192 | 2500, |
157 | 2600, | 193 | 2600, |
158 | 2700, | 194 | 2700, |
@@ -162,8 +198,12 @@ static const float codes8[] = { | |||
162 | 3100, | 198 | 3100, |
163 | 3200 | 199 | 3200 |
164 | }; | 200 | }; |
165 | /* codebook/lsp10.txt */ | 201 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp10.txt */ |
202 | #ifdef __EMBEDDED__ | ||
166 | static const float codes9[] = { | 203 | static const float codes9[] = { |
204 | #else | ||
205 | static float codes9[] = { | ||
206 | #endif | ||
167 | 2900, | 207 | 2900, |
168 | 3100, | 208 | 3100, |
169 | 3300, | 209 | 3300, |
@@ -171,70 +211,70 @@ static const float codes9[] = { | |||
171 | }; | 211 | }; |
172 | 212 | ||
173 | const struct lsp_codebook lsp_cb[] = { | 213 | const struct lsp_codebook lsp_cb[] = { |
174 | /* codebook/lsp1.txt */ | 214 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp1.txt */ |
175 | { | 215 | { |
176 | 1, | 216 | 1, |
177 | 4, | 217 | 4, |
178 | 16, | 218 | 16, |
179 | codes0 | 219 | codes0 |
180 | }, | 220 | }, |
181 | /* codebook/lsp2.txt */ | 221 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp2.txt */ |
182 | { | 222 | { |
183 | 1, | 223 | 1, |
184 | 4, | 224 | 4, |
185 | 16, | 225 | 16, |
186 | codes1 | 226 | codes1 |
187 | }, | 227 | }, |
188 | /* codebook/lsp3.txt */ | 228 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp3.txt */ |
189 | { | 229 | { |
190 | 1, | 230 | 1, |
191 | 4, | 231 | 4, |
192 | 16, | 232 | 16, |
193 | codes2 | 233 | codes2 |
194 | }, | 234 | }, |
195 | /* codebook/lsp4.txt */ | 235 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp4.txt */ |
196 | { | 236 | { |
197 | 1, | 237 | 1, |
198 | 4, | 238 | 4, |
199 | 16, | 239 | 16, |
200 | codes3 | 240 | codes3 |
201 | }, | 241 | }, |
202 | /* codebook/lsp5.txt */ | 242 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp5.txt */ |
203 | { | 243 | { |
204 | 1, | 244 | 1, |
205 | 4, | 245 | 4, |
206 | 16, | 246 | 16, |
207 | codes4 | 247 | codes4 |
208 | }, | 248 | }, |
209 | /* codebook/lsp6.txt */ | 249 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp6.txt */ |
210 | { | 250 | { |
211 | 1, | 251 | 1, |
212 | 4, | 252 | 4, |
213 | 16, | 253 | 16, |
214 | codes5 | 254 | codes5 |
215 | }, | 255 | }, |
216 | /* codebook/lsp7.txt */ | 256 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp7.txt */ |
217 | { | 257 | { |
218 | 1, | 258 | 1, |
219 | 4, | 259 | 4, |
220 | 16, | 260 | 16, |
221 | codes6 | 261 | codes6 |
222 | }, | 262 | }, |
223 | /* codebook/lsp8.txt */ | 263 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp8.txt */ |
224 | { | 264 | { |
225 | 1, | 265 | 1, |
226 | 3, | 266 | 3, |
227 | 8, | 267 | 8, |
228 | codes7 | 268 | codes7 |
229 | }, | 269 | }, |
230 | /* codebook/lsp9.txt */ | 270 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp9.txt */ |
231 | { | 271 | { |
232 | 1, | 272 | 1, |
233 | 3, | 273 | 3, |
234 | 8, | 274 | 8, |
235 | codes8 | 275 | codes8 |
236 | }, | 276 | }, |
237 | /* codebook/lsp10.txt */ | 277 | /* /Users/erdgeist/Coding/codec2/src/codebook/lsp10.txt */ |
238 | { | 278 | { |
239 | 1, | 279 | 1, |
240 | 2, | 280 | 2, |
diff --git a/codebookd.c b/codebookd.c index 5816402..5ca8651 100644 --- a/codebookd.c +++ b/codebookd.c | |||
@@ -1,14 +1,18 @@ | |||
1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ | 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * This intermediary file and the files that used to create it are under | 4 | * This intermediary file and the files that used to create it are under |
5 | * The LGPL. See the file COPYING. | 5 | * The LGPL. See the file COPYING. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "defines.h" | 8 | #include "defines.h" |
9 | 9 | ||
10 | /* codebook/dlsp1.txt */ | 10 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp1.txt */ |
11 | #ifdef __EMBEDDED__ | ||
11 | static const float codes0[] = { | 12 | static const float codes0[] = { |
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
12 | 25, | 16 | 25, |
13 | 50, | 17 | 50, |
14 | 75, | 18 | 75, |
@@ -42,8 +46,12 @@ static const float codes0[] = { | |||
42 | 775, | 46 | 775, |
43 | 800 | 47 | 800 |
44 | }; | 48 | }; |
45 | /* codebook/dlsp2.txt */ | 49 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp2.txt */ |
50 | #ifdef __EMBEDDED__ | ||
46 | static const float codes1[] = { | 51 | static const float codes1[] = { |
52 | #else | ||
53 | static float codes1[] = { | ||
54 | #endif | ||
47 | 25, | 55 | 25, |
48 | 50, | 56 | 50, |
49 | 75, | 57 | 75, |
@@ -77,8 +85,12 @@ static const float codes1[] = { | |||
77 | 775, | 85 | 775, |
78 | 800 | 86 | 800 |
79 | }; | 87 | }; |
80 | /* codebook/dlsp3.txt */ | 88 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp3.txt */ |
89 | #ifdef __EMBEDDED__ | ||
81 | static const float codes2[] = { | 90 | static const float codes2[] = { |
91 | #else | ||
92 | static float codes2[] = { | ||
93 | #endif | ||
82 | 25, | 94 | 25, |
83 | 50, | 95 | 50, |
84 | 75, | 96 | 75, |
@@ -112,8 +124,12 @@ static const float codes2[] = { | |||
112 | 775, | 124 | 775, |
113 | 800 | 125 | 800 |
114 | }; | 126 | }; |
115 | /* codebook/dlsp4.txt */ | 127 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp4.txt */ |
128 | #ifdef __EMBEDDED__ | ||
116 | static const float codes3[] = { | 129 | static const float codes3[] = { |
130 | #else | ||
131 | static float codes3[] = { | ||
132 | #endif | ||
117 | 25, | 133 | 25, |
118 | 50, | 134 | 50, |
119 | 75, | 135 | 75, |
@@ -147,8 +163,12 @@ static const float codes3[] = { | |||
147 | 1350, | 163 | 1350, |
148 | 1400 | 164 | 1400 |
149 | }; | 165 | }; |
150 | /* codebook/dlsp5.txt */ | 166 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp5.txt */ |
167 | #ifdef __EMBEDDED__ | ||
151 | static const float codes4[] = { | 168 | static const float codes4[] = { |
169 | #else | ||
170 | static float codes4[] = { | ||
171 | #endif | ||
152 | 25, | 172 | 25, |
153 | 50, | 173 | 50, |
154 | 75, | 174 | 75, |
@@ -182,8 +202,12 @@ static const float codes4[] = { | |||
182 | 1350, | 202 | 1350, |
183 | 1400 | 203 | 1400 |
184 | }; | 204 | }; |
185 | /* codebook/dlsp6.txt */ | 205 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp6.txt */ |
206 | #ifdef __EMBEDDED__ | ||
186 | static const float codes5[] = { | 207 | static const float codes5[] = { |
208 | #else | ||
209 | static float codes5[] = { | ||
210 | #endif | ||
187 | 25, | 211 | 25, |
188 | 50, | 212 | 50, |
189 | 75, | 213 | 75, |
@@ -217,8 +241,12 @@ static const float codes5[] = { | |||
217 | 1350, | 241 | 1350, |
218 | 1400 | 242 | 1400 |
219 | }; | 243 | }; |
220 | /* codebook/dlsp7.txt */ | 244 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp7.txt */ |
245 | #ifdef __EMBEDDED__ | ||
221 | static const float codes6[] = { | 246 | static const float codes6[] = { |
247 | #else | ||
248 | static float codes6[] = { | ||
249 | #endif | ||
222 | 25, | 250 | 25, |
223 | 50, | 251 | 50, |
224 | 75, | 252 | 75, |
@@ -252,8 +280,12 @@ static const float codes6[] = { | |||
252 | 775, | 280 | 775, |
253 | 800 | 281 | 800 |
254 | }; | 282 | }; |
255 | /* codebook/dlsp8.txt */ | 283 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp8.txt */ |
284 | #ifdef __EMBEDDED__ | ||
256 | static const float codes7[] = { | 285 | static const float codes7[] = { |
286 | #else | ||
287 | static float codes7[] = { | ||
288 | #endif | ||
257 | 25, | 289 | 25, |
258 | 50, | 290 | 50, |
259 | 75, | 291 | 75, |
@@ -287,8 +319,12 @@ static const float codes7[] = { | |||
287 | 775, | 319 | 775, |
288 | 800 | 320 | 800 |
289 | }; | 321 | }; |
290 | /* codebook/dlsp9.txt */ | 322 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp9.txt */ |
323 | #ifdef __EMBEDDED__ | ||
291 | static const float codes8[] = { | 324 | static const float codes8[] = { |
325 | #else | ||
326 | static float codes8[] = { | ||
327 | #endif | ||
292 | 25, | 328 | 25, |
293 | 50, | 329 | 50, |
294 | 75, | 330 | 75, |
@@ -322,8 +358,12 @@ static const float codes8[] = { | |||
322 | 775, | 358 | 775, |
323 | 800 | 359 | 800 |
324 | }; | 360 | }; |
325 | /* codebook/dlsp10.txt */ | 361 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp10.txt */ |
362 | #ifdef __EMBEDDED__ | ||
326 | static const float codes9[] = { | 363 | static const float codes9[] = { |
364 | #else | ||
365 | static float codes9[] = { | ||
366 | #endif | ||
327 | 25, | 367 | 25, |
328 | 50, | 368 | 50, |
329 | 75, | 369 | 75, |
@@ -359,70 +399,70 @@ static const float codes9[] = { | |||
359 | }; | 399 | }; |
360 | 400 | ||
361 | const struct lsp_codebook lsp_cbd[] = { | 401 | const struct lsp_codebook lsp_cbd[] = { |
362 | /* codebook/dlsp1.txt */ | 402 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp1.txt */ |
363 | { | 403 | { |
364 | 1, | 404 | 1, |
365 | 5, | 405 | 5, |
366 | 32, | 406 | 32, |
367 | codes0 | 407 | codes0 |
368 | }, | 408 | }, |
369 | /* codebook/dlsp2.txt */ | 409 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp2.txt */ |
370 | { | 410 | { |
371 | 1, | 411 | 1, |
372 | 5, | 412 | 5, |
373 | 32, | 413 | 32, |
374 | codes1 | 414 | codes1 |
375 | }, | 415 | }, |
376 | /* codebook/dlsp3.txt */ | 416 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp3.txt */ |
377 | { | 417 | { |
378 | 1, | 418 | 1, |
379 | 5, | 419 | 5, |
380 | 32, | 420 | 32, |
381 | codes2 | 421 | codes2 |
382 | }, | 422 | }, |
383 | /* codebook/dlsp4.txt */ | 423 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp4.txt */ |
384 | { | 424 | { |
385 | 1, | 425 | 1, |
386 | 5, | 426 | 5, |
387 | 32, | 427 | 32, |
388 | codes3 | 428 | codes3 |
389 | }, | 429 | }, |
390 | /* codebook/dlsp5.txt */ | 430 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp5.txt */ |
391 | { | 431 | { |
392 | 1, | 432 | 1, |
393 | 5, | 433 | 5, |
394 | 32, | 434 | 32, |
395 | codes4 | 435 | codes4 |
396 | }, | 436 | }, |
397 | /* codebook/dlsp6.txt */ | 437 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp6.txt */ |
398 | { | 438 | { |
399 | 1, | 439 | 1, |
400 | 5, | 440 | 5, |
401 | 32, | 441 | 32, |
402 | codes5 | 442 | codes5 |
403 | }, | 443 | }, |
404 | /* codebook/dlsp7.txt */ | 444 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp7.txt */ |
405 | { | 445 | { |
406 | 1, | 446 | 1, |
407 | 5, | 447 | 5, |
408 | 32, | 448 | 32, |
409 | codes6 | 449 | codes6 |
410 | }, | 450 | }, |
411 | /* codebook/dlsp8.txt */ | 451 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp8.txt */ |
412 | { | 452 | { |
413 | 1, | 453 | 1, |
414 | 5, | 454 | 5, |
415 | 32, | 455 | 32, |
416 | codes7 | 456 | codes7 |
417 | }, | 457 | }, |
418 | /* codebook/dlsp9.txt */ | 458 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp9.txt */ |
419 | { | 459 | { |
420 | 1, | 460 | 1, |
421 | 5, | 461 | 5, |
422 | 32, | 462 | 32, |
423 | codes8 | 463 | codes8 |
424 | }, | 464 | }, |
425 | /* codebook/dlsp10.txt */ | 465 | /* /Users/erdgeist/Coding/codec2/src/codebook/dlsp10.txt */ |
426 | { | 466 | { |
427 | 1, | 467 | 1, |
428 | 5, | 468 | 5, |
diff --git a/codebookge.c b/codebookge.c index 5bcb623..8bb0329 100644 --- a/codebookge.c +++ b/codebookge.c | |||
@@ -1,14 +1,18 @@ | |||
1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ | 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * This intermediary file and the files that used to create it are under | 4 | * This intermediary file and the files that used to create it are under |
5 | * The LGPL. See the file COPYING. | 5 | * The LGPL. See the file COPYING. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "defines.h" | 8 | #include "defines.h" |
9 | 9 | ||
10 | /* codebook/gecb.txt */ | 10 | /* /Users/erdgeist/Coding/codec2/src/codebook/gecb.txt */ |
11 | #ifdef __EMBEDDED__ | ||
11 | static const float codes0[] = { | 12 | static const float codes0[] = { |
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
12 | 2.71, 12.0184, | 16 | 2.71, 12.0184, |
13 | 0.04675, -2.73881, | 17 | 0.04675, -2.73881, |
14 | 0.120993, 8.38895, | 18 | 0.120993, 8.38895, |
@@ -268,7 +272,7 @@ static const float codes0[] = { | |||
268 | }; | 272 | }; |
269 | 273 | ||
270 | const struct lsp_codebook ge_cb[] = { | 274 | const struct lsp_codebook ge_cb[] = { |
271 | /* codebook/gecb.txt */ | 275 | /* /Users/erdgeist/Coding/codec2/src/codebook/gecb.txt */ |
272 | { | 276 | { |
273 | 2, | 277 | 2, |
274 | 8, | 278 | 8, |
diff --git a/codebookjvm.c b/codebookjmv.c index 86f5b83..75af664 100644 --- a/codebookjvm.c +++ b/codebookjmv.c | |||
@@ -1,14 +1,18 @@ | |||
1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ | 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * This intermediary file and the files that used to create it are under | 4 | * This intermediary file and the files that used to create it are under |
5 | * The LGPL. See the file COPYING. | 5 | * The LGPL. See the file COPYING. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "defines.h" | 8 | #include "defines.h" |
9 | 9 | ||
10 | /* codebook/lspjvm1.txt */ | 10 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspjmv1.txt */ |
11 | #ifdef __EMBEDDED__ | ||
11 | static const float codes0[] = { | 12 | static const float codes0[] = { |
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
12 | 0.435217, 0.668864, 1.0103, 1.22042, 1.50398, 1.78468, 2.13546, 2.35747, 2.61891, 2.73804, | 16 | 0.435217, 0.668864, 1.0103, 1.22042, 1.50398, 1.78468, 2.13546, 2.35747, 2.61891, 2.73804, |
13 | 0.179285, 0.33316, 0.500638, 0.79695, 1.03999, 1.23497, 1.6523, 1.84823, 2.62556, 2.80497, | 17 | 0.179285, 0.33316, 0.500638, 0.79695, 1.03999, 1.23497, 1.6523, 1.84823, 2.62556, 2.80497, |
14 | 0.268785, 0.356576, 0.595753, 1.04434, 1.24938, 1.42868, 1.68699, 1.86469, 2.33991, 2.5138, | 18 | 0.268785, 0.356576, 0.595753, 1.04434, 1.24938, 1.42868, 1.68699, 1.86469, 2.33991, 2.5138, |
@@ -522,8 +526,12 @@ static const float codes0[] = { | |||
522 | 0.427795, 0.519003, 0.771284, 0.93724, 1.08662, 1.60988, 1.87875, 2.05279, 2.53412, 2.65715, | 526 | 0.427795, 0.519003, 0.771284, 0.93724, 1.08662, 1.60988, 1.87875, 2.05279, 2.53412, 2.65715, |
523 | 0.22437, 0.317969, 0.439666, 0.812931, 1.3985, 1.62663, 1.79418, 2.114, 2.30916, 2.49684 | 527 | 0.22437, 0.317969, 0.439666, 0.812931, 1.3985, 1.62663, 1.79418, 2.114, 2.30916, 2.49684 |
524 | }; | 528 | }; |
525 | /* codebook/lspjvm2.txt */ | 529 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspjmv2.txt */ |
530 | #ifdef __EMBEDDED__ | ||
526 | static const float codes1[] = { | 531 | static const float codes1[] = { |
532 | #else | ||
533 | static float codes1[] = { | ||
534 | #endif | ||
527 | 0.005167, -0.03731, -0.002159, 0.016849, 0.130396, | 535 | 0.005167, -0.03731, -0.002159, 0.016849, 0.130396, |
528 | 0.039445, 0.03168, -0.074412, -0.031499, 0.060536, | 536 | 0.039445, 0.03168, -0.074412, -0.031499, 0.060536, |
529 | 0.019479, -0.030564, -0.048137, -0.056279, -0.027829, | 537 | 0.019479, -0.030564, -0.048137, -0.056279, -0.027829, |
@@ -1037,8 +1045,12 @@ static const float codes1[] = { | |||
1037 | -0.033256, -0.053774, 0.049001, -0.002339, 0.013545, | 1045 | -0.033256, -0.053774, 0.049001, -0.002339, 0.013545, |
1038 | -0.006432, -0.012089, -0.086842, 0.104105, 0.061991 | 1046 | -0.006432, -0.012089, -0.086842, 0.104105, 0.061991 |
1039 | }; | 1047 | }; |
1040 | /* codebook/lspjvm3.txt */ | 1048 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspjmv3.txt */ |
1049 | #ifdef __EMBEDDED__ | ||
1041 | static const float codes2[] = { | 1050 | static const float codes2[] = { |
1051 | #else | ||
1052 | static float codes2[] = { | ||
1053 | #endif | ||
1042 | 0.007066, 0.075781, -0.070082, -0.092014, -0.066477, | 1054 | 0.007066, 0.075781, -0.070082, -0.092014, -0.066477, |
1043 | 0.09051, 0.106622, 0.025911, -0.01676, 0.003724, | 1055 | 0.09051, 0.106622, 0.025911, -0.01676, 0.003724, |
1044 | -0.024628, 0.058332, 0.012876, 0.059557, -0.002092, | 1056 | -0.024628, 0.058332, 0.012876, 0.059557, -0.002092, |
@@ -1553,22 +1565,22 @@ static const float codes2[] = { | |||
1553 | 0.086151, -0.113571, -0.019466, -0.009167, 0.003662 | 1565 | 0.086151, -0.113571, -0.019466, -0.009167, 0.003662 |
1554 | }; | 1566 | }; |
1555 | 1567 | ||
1556 | const struct lsp_codebook lsp_cbjvm[] = { | 1568 | const struct lsp_codebook lsp_cbjmv[] = { |
1557 | /* codebook/lspjvm1.txt */ | 1569 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspjmv1.txt */ |
1558 | { | 1570 | { |
1559 | 10, | 1571 | 10, |
1560 | 9, | 1572 | 9, |
1561 | 512, | 1573 | 512, |
1562 | codes0 | 1574 | codes0 |
1563 | }, | 1575 | }, |
1564 | /* codebook/lspjvm2.txt */ | 1576 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspjmv2.txt */ |
1565 | { | 1577 | { |
1566 | 5, | 1578 | 5, |
1567 | 9, | 1579 | 9, |
1568 | 512, | 1580 | 512, |
1569 | codes1 | 1581 | codes1 |
1570 | }, | 1582 | }, |
1571 | /* codebook/lspjvm3.txt */ | 1583 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspjmv3.txt */ |
1572 | { | 1584 | { |
1573 | 5, | 1585 | 5, |
1574 | 9, | 1586 | 9, |
diff --git a/codebooklspmelvq.c b/codebooklspmelvq.c deleted file mode 100644 index f49ff36..0000000 --- a/codebooklspmelvq.c +++ /dev/null | |||
@@ -1,247 +0,0 @@ | |||
1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ | ||
2 | |||
3 | /* | ||
4 | * This intermediary file and the files that used to create it are under | ||
5 | * The LGPL. See the file COPYING. | ||
6 | */ | ||
7 | |||
8 | #include "defines.h" | ||
9 | |||
10 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspmelvq1.txt */ | ||
11 | #ifdef __EMBEDDED__ | ||
12 | static const float codes0[] = { | ||
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
16 | 640.185, 893.139, 1393.85, 1494.06, 1656.26, 1700.82, | ||
17 | 558.516, 716.906, 1057.36, 1182.62, 1503.8, 1610.03, | ||
18 | 615.108, 769.622, 1120.16, 1222.84, 1366.46, 1465.05, | ||
19 | 663.458, 736.833, 964.764, 1043.54, 1623.17, 1681.29, | ||
20 | 487.957, 577.723, 1017.43, 1177.04, 1552.1, 1615.69, | ||
21 | 536.099, 733.407, 1292.28, 1406.09, 1577.7, 1637.49, | ||
22 | 473.015, 542.559, 877.397, 1285.82, 1591.04, 1647.44, | ||
23 | 525.343, 652.014, 1206.83, 1493.96, 1647.97, 1698.3, | ||
24 | 510.887, 572.868, 945.226, 1445.68, 1678.17, 1705.53, | ||
25 | 534.915, 721.265, 1275.92, 1415.76, 1648.5, 1695.73, | ||
26 | 865.189, 1047, 1267.14, 1389.32, 1646.57, 1696.97, | ||
27 | 608.033, 869.887, 1300.95, 1432.87, 1639.74, 1689.41, | ||
28 | 554.972, 649.352, 866.845, 979.873, 1645.31, 1695.39, | ||
29 | 696.079, 813.97, 1102.49, 1219.79, 1536.49, 1621.94, | ||
30 | 553.879, 691.097, 1200.84, 1339.34, 1629.08, 1683.5, | ||
31 | 778.561, 997.776, 1258.63, 1390.34, 1601.99, 1657.86, | ||
32 | 713.107, 778.893, 992.875, 1051.95, 1497.45, 1650.66, | ||
33 | 490.27, 598.18, 1116.02, 1244.13, 1622.26, 1672.21, | ||
34 | 448.556, 512.085, 1271.7, 1448.18, 1579.37, 1642.48, | ||
35 | 465.688, 535.312, 1099.19, 1535.79, 1684.29, 1710.9, | ||
36 | 812.222, 1087.53, 1470.44, 1559.73, 1692.18, 1726.38, | ||
37 | 428.174, 489.426, 1160.33, 1409.3, 1597.5, 1651.3, | ||
38 | 712.81, 957.56, 1433.02, 1516.37, 1675.39, 1710.06, | ||
39 | 717.255, 934.073, 1305.2, 1436.72, 1647.2, 1693.09, | ||
40 | 492.888, 580.393, 1339.52, 1461.07, 1592, 1653.42, | ||
41 | 550.467, 675.888, 990.888, 1177.44, 1615.64, 1658, | ||
42 | 714.528, 801.792, 1072.94, 1146.08, 1637.06, 1706.58, | ||
43 | 513.819, 590.989, 798.691, 895.755, 1557.76, 1624.56, | ||
44 | 436.653, 518.413, 1281.99, 1547.08, 1685.12, 1717.76, | ||
45 | 681.854, 758.354, 1046.65, 1120.92, 1412.25, 1603.42, | ||
46 | 873.962, 1118.49, 1376.61, 1465.07, 1665.38, 1707.18, | ||
47 | 553.529, 634.092, 1144.77, 1284.8, 1542.87, 1620.63, | ||
48 | 448.532, 519.097, 1054.57, 1319.66, 1591.26, 1649.85, | ||
49 | 742.267, 885.293, 1152.83, 1318.51, 1569.36, 1631.45, | ||
50 | 529.03, 654.522, 1355.76, 1511.75, 1662.39, 1706.4, | ||
51 | 463.794, 597.77, 1176.05, 1366.13, 1629.37, 1678.01, | ||
52 | 626.936, 706.66, 1058.04, 1323.62, 1473.28, 1599.68, | ||
53 | 477.322, 615.5, 1488.89, 1550.5, 1683.1, 1712.34, | ||
54 | 547.442, 815.442, 1313.38, 1486.96, 1671.97, 1717.4, | ||
55 | 610.671, 819.955, 1219.11, 1363.66, 1592.05, 1654.31, | ||
56 | 547.414, 746.54, 1438.43, 1517.72, 1659.64, 1695.57, | ||
57 | 604.823, 821.146, 1137.94, 1358.29, 1598.94, 1655.64, | ||
58 | 525.935, 616.739, 1060.13, 1427.33, 1593.35, 1657.48, | ||
59 | 622.5, 762.143, 1318.65, 1410.96, 1618.12, 1680.06, | ||
60 | 436.917, 516.583, 1390.29, 1475.86, 1594.71, 1633.74, | ||
61 | 792.487, 1031.24, 1362.62, 1472.68, 1649.26, 1697.35, | ||
62 | 457.707, 526.207, 865.966, 1120.47, 1564.83, 1625.28, | ||
63 | 526.39, 624.21, 1269.65, 1374.23, 1558.07, 1620.96, | ||
64 | 483.768, 573.505, 1440.66, 1512.43, 1622.37, 1671.31, | ||
65 | 953.061, 1194.03, 1416.67, 1515.82, 1678.82, 1718.21, | ||
66 | 499.947, 627.358, 1299.94, 1394.23, 1643.17, 1685.33, | ||
67 | 648.723, 838.181, 1225.5, 1383.45, 1637.46, 1691.67, | ||
68 | 672.588, 1022.6, 1346.21, 1443.75, 1651.15, 1695.43, | ||
69 | 581.833, 674.944, 955.167, 1020.5, 1370.5, 1503.11, | ||
70 | 536.143, 652.531, 1243.84, 1315.27, 1425.1, 1505.73, | ||
71 | 560.558, 786.65, 1224.66, 1373.98, 1630.06, 1682.68, | ||
72 | 591.926, 783.722, 982, 1140.81, 1581.61, 1625.28, | ||
73 | 548.537, 644.524, 940.451, 1048.74, 1557.89, 1609.48, | ||
74 | 516.916, 723.253, 1135.95, 1309.19, 1600.08, 1669.48, | ||
75 | 426.521, 506.077, 1457.73, 1535.02, 1641.35, 1678.45, | ||
76 | 645.189, 776.595, 1020.78, 1240.07, 1597, 1648.7, | ||
77 | 637.105, 941.474, 1242.21, 1372.49, 1646.7, 1694.8, | ||
78 | 691.228, 788.141, 1202.12, 1294.89, 1626.97, 1681.77, | ||
79 | 699.08, 886.655, 1300.9, 1399.28, 1579.94, 1646.79 | ||
80 | }; | ||
81 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspmelvq2.txt */ | ||
82 | #ifdef __EMBEDDED__ | ||
83 | static const float codes1[] = { | ||
84 | #else | ||
85 | static float codes1[] = { | ||
86 | #endif | ||
87 | 4.44342, 51.1708, 7.45726, -27.4373, -18.5056, -18.1989, | ||
88 | 51.58, 63.3166, 57.7796, -44.1591, -18.4834, -6.93392, | ||
89 | -20.2795, -21.7454, 4.66947, 52.1569, 30.4367, 36.8582, | ||
90 | -29.1104, -5.63933, -3.45383, -63.0261, -20.4423, -19.0485, | ||
91 | 2.91622, 40.8374, 16.579, -51.8461, 38.5045, 18.1728, | ||
92 | -20.6977, -11.4022, -36.6173, -16.6116, -56.8965, -24.301, | ||
93 | -20.2385, 26.6332, 33.1191, 27.6284, -36.7493, -25.6041, | ||
94 | 54.9871, 0.71748, 23.0674, -22.1031, 11.6643, 10.9938, | ||
95 | -62.7215, 21.7547, 21.2907, -7.64891, -4.5533, -9.71777, | ||
96 | -9.56338, -3.85841, 25.0454, -9.45216, 6.05017, 5.35043, | ||
97 | 47.3823, 56.6122, -27.0315, -24.67, 4.86343, -0.225495, | ||
98 | 26.3997, 26.7857, -1.66167, 62.8366, -19.7653, -8.55169, | ||
99 | -8.77648, -9.04545, -7.88996, 28.2433, -35.0963, -21.9709, | ||
100 | 14.8423, 25.4563, -56.1262, -50.2934, -22.9393, -15.8113, | ||
101 | 4.94186, 27.7798, 8.34579, 10.8553, -3.12587, -3.97807, | ||
102 | 12.6426, -52.2317, 37.2487, -57.2067, -14.5125, -5.54035, | ||
103 | 13.485, 15.3246, -23.9644, -21.3135, 19.5779, 14.1597, | ||
104 | -55.3543, -45.2077, 10.5185, 43.0461, -24.9859, -19.3484, | ||
105 | 27.7226, 32.1882, 20.0321, 24.3328, -72.8194, -51.1823, | ||
106 | -31.3818, -5.25745, -43.7806, 14.1312, 17.6392, 9.81024, | ||
107 | -48.26, -26.2973, -44.1428, -31.9001, 22.5085, -0.467938, | ||
108 | 7.37202, -7.79071, -12.5732, 27.1074, 9.34052, 14.4477, | ||
109 | 14.5295, 8.82597, 57.0009, -16.3234, -32.4142, -21.0224, | ||
110 | 32.4616, 48.6062, 38.5452, 9.77182, 1.82856, 11.5063, | ||
111 | -43.8275, -22.6263, -29.8278, 13.6115, 9.66849, -63.5218, | ||
112 | -11.9967, 2.74308, -73.6375, -20.9809, -4.11839, 7.71405, | ||
113 | 24.0162, -2.29513, -6.80983, -26.4043, -21.8529, -16.3381, | ||
114 | -16.1484, 35.9086, -3.0837, 3.83958, 42.3003, 17.5003, | ||
115 | 54.1225, -48.7513, -14.8712, -38.1256, 15.2903, 7.33079, | ||
116 | 53.0929, 13.9221, 10.6536, 24.345, -16.5952, -16.0365, | ||
117 | 33.1415, 38.5714, -26.0251, 22.021, 15.6866, 13.2593, | ||
118 | 15.7194, -49.4061, 31.4552, 10.1896, 0.219911, 1.62902, | ||
119 | 4.10868, 14.2755, 58.475, -1.16668, 52.6265, 43.4938, | ||
120 | 358.653, -112.587, 85.9867, 52.08, -52.88, -249.24, | ||
121 | -12.5792, -6.64039, -33.0106, 1.51449, 50.3259, 61.6091, | ||
122 | -6.81685, 14.3146, 14.1563, 53.6363, 83.6051, 38.174, | ||
123 | -18.0006, 41.3575, -46.3736, 8.47794, -10.4611, -11.3847, | ||
124 | 28.7711, 31.4689, -39.5744, 1.43977, -37.7309, -30.5309, | ||
125 | -34.4692, -11.0778, 44.4681, -60.0045, -44.9729, -34.8364, | ||
126 | 38.7401, 41.0529, -7.92946, 20.0279, 74.4246, 54.6498, | ||
127 | 81.8008, 133.531, -5.47375, 34.4759, 75.7417, 52.6112, | ||
128 | -61.5067, -76.6328, -47.2471, -43.5928, -9.46878, 0.832598, | ||
129 | -11.544, -44.7728, -13.9257, -3.32122, 24.816, 21.9064, | ||
130 | 2.83945, -45.0522, -36.8776, -14.7577, -11.9912, -8.75366, | ||
131 | -8.97657, -14.0499, 39.2628, 48.8038, -14.3789, -4.79625, | ||
132 | 31.6292, 32.0168, 5.52278, -79.8411, -24.1789, -15.7597, | ||
133 | 15.893, 10.4667, -43.9057, -20.4885, 80.7594, 6.8023, | ||
134 | 22.3285, -69.4942, -5.16156, 48.8868, 4.01995, -3.04376, | ||
135 | 31.4062, -20.0952, -55.1259, 0.505988, 20.86, 15.0816, | ||
136 | -12.9696, 37.2548, 18.1009, 51.0767, 18.2053, 19.8474, | ||
137 | -45.4855, -45.3454, -4.22795, -15.8693, -6.07272, -1.99631, | ||
138 | -9.25462, 45.0241, 70.2879, -44.4484, 2.63165, 4.15336, | ||
139 | -51.1589, -27.7586, 19.7999, -9.87882, 63.4125, 48.3124, | ||
140 | -8.94084, -13.4815, -44.9602, 52.839, -17.2582, -1.59439, | ||
141 | 23.18, -3.00374, 33.162, 31.5424, 29.111, 25.9327, | ||
142 | -28.4665, -10.6868, 88.7543, -3.88024, 17.5881, 13.7336, | ||
143 | -10.6578, 7.43021, -20.945, -17.6491, -11.2815, -10.8001, | ||
144 | -35.6182, -6.90301, 3.92829, 26.9695, 2.8894, 5.01685, | ||
145 | -3.78263, -19.2095, -10.5568, -67.7468, 20.3733, 29.552, | ||
146 | 53.8109, -33.8374, -27.8223, -7.73289, -31.3462, -23.5678, | ||
147 | -38.8762, -17.7679, 11.457, 28.4607, 50.7006, -19.2488, | ||
148 | -44.6024, -60.2806, 56.35, 21.7545, 5.23677, 7.66608, | ||
149 | -3.80758, -39.1425, 28.8305, -3.09285, -42.7534, -25.1803, | ||
150 | 45.2559, 28.8742, 60.0723, 64.461, 3.51203, -27.883 | ||
151 | }; | ||
152 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspmelvq3.txt */ | ||
153 | #ifdef __EMBEDDED__ | ||
154 | static const float codes2[] = { | ||
155 | #else | ||
156 | static float codes2[] = { | ||
157 | #endif | ||
158 | -9.63558, 27.5501, 15.4445, -4.34872, -1.8587, 1.27054, | ||
159 | -15.5343, 23.0515, -15.4436, -2.01887, -6.19433, -13.5085, | ||
160 | 8.38867, -1.60998, -32.3903, 10.1765, 1.9467, 12.2454, | ||
161 | -3.06306, -9.55983, 14.367, -1.87159, 19.6192, -3.78366, | ||
162 | -18.495, -13.3811, -23.8928, -20.3745, -6.87856, -17.4887, | ||
163 | 15.4925, 14.707, -0.0697855, 15.7541, 12.6051, -3.19768, | ||
164 | 9.60466, -4.56494, 10.1616, 15.5594, 6.89224, -31.5602, | ||
165 | -11.5625, -23.0872, 34.9163, 12.3052, 7.67426, -1.26298, | ||
166 | 2.5486, -3.90251, -19.1132, 7.6131, -31.0016, 12.4759, | ||
167 | 2.74156, 12.4124, -39.5057, -0.325024, -22.9186, -28.5606, | ||
168 | 6.30148, 15.4402, -2.6284, -20.1603, 5.22906, -12.3451, | ||
169 | -6.91862, 16.6335, -1.65064, 2.99602, -23.9479, -1.43947, | ||
170 | -14.3907, -31.417, 10.1113, 1.70013, -21.5733, 4.736, | ||
171 | -1.67171, 6.22751, -13.7187, 21.0936, -9.69243, -10.5756, | ||
172 | 2.15266, 21.2198, -13.0171, -1.43135, 18.8831, 10.6664, | ||
173 | 13.8913, 27.3565, 0.472838, -7.40477, -14.8705, 25.7448, | ||
174 | 28.402, -2.05484, -9.32712, -17.3169, 15.643, 6.96908, | ||
175 | -15.863, -17.8482, -24.9238, 12.5574, 7.17566, 0.0161972, | ||
176 | 5.99291, -41.0228, 1.95791, -6.78012, 9.20162, 4.6234, | ||
177 | -6.33629, -7.61679, 27.7318, -8.9214, -14.1931, 7.88247, | ||
178 | -12.2367, -21.245, -2.5927, 13.7776, -2.7864, -24.5072, | ||
179 | 23.15, -9.93687, -2.92559, 3.88086, 11.2667, 11.1998, | ||
180 | 9.67437, -9.4269, 6.2582, 36.5694, 2.88654, 1.82052, | ||
181 | 15.385, -2.88243, 19.8377, -14.5111, 5.92264, -2.55757, | ||
182 | -20.9648, 3.76147, 18.5074, -13.5547, -7.84261, -19.98, | ||
183 | 24.6032, 16.989, -19.1622, 1.35535, -0.0122027, 0.166227, | ||
184 | 9.98886, -6.89666, -20.5111, -2.89196, 2.58467, -17.049, | ||
185 | -9.17761, -23.7209, 12.6088, -18.2654, 2.17718, -13.0865, | ||
186 | -9.73326, -12.2682, 6.80914, 20.3469, -10.2912, 4.85191, | ||
187 | -5.19406, 6.78014, 18.0099, 14.3782, -0.124328, -10.0141, | ||
188 | -4.69806, 6.71393, -19.1371, 8.19814, 23.3987, -10.3316, | ||
189 | 1.02965, -4.63654, 21.9822, 11.5088, -30.9617, -20.6354, | ||
190 | -33.2824, 31.4666, -11.4837, 11.5144, -1.36834, 9.44599, | ||
191 | -37.5431, -3.16317, -2.09497, -2.62712, 40.4714, -33.0527, | ||
192 | -8.79595, -15.5174, -15.7916, 7.97003, 37.2542, 40.7063, | ||
193 | -14.7261, -12.6884, 2.42105, -10.2686, 25.9033, 14.8525, | ||
194 | 22.9598, -16.6224, -3.64949, 4.44269, -22.3897, 13.6968, | ||
195 | -10.874, 4.18931, -24.2284, -3.63764, -15.1379, 40.9515, | ||
196 | 28.2393, -8.63225, -12.544, 28.8282, -0.987894, -4.9824, | ||
197 | -25.0777, -0.481678, -3.37082, 5.55114, -9.89898, -8.07628, | ||
198 | 23.3581, 3.12034, -8.63348, 0.63042, -18.2216, -22.1886, | ||
199 | 44.9505, 19.8267, 23.7129, 8.58075, 7.80458, 1.78796, | ||
200 | -8.13112, -2.1262, -7.12776, -25.0529, -16.7287, 8.41402, | ||
201 | 2.01965, 19.2579, 20.0963, 5.99199, 28.1098, 5.96128, | ||
202 | 2.42493, -6.33216, -26.5858, -23.8607, 8.27049, 3.05805, | ||
203 | 0.0153248, 0.446112, -4.92759, 19.0023, 22.7346, 15.5451, | ||
204 | -7.39591, 40.285, 10.8414, 25.7961, -8.81069, -13.5, | ||
205 | 5.81306, 11.2384, 6.93765, -9.43067, 9.51418, 22.9709, | ||
206 | -9.17611, -16.4993, -1.56929, -2.9111, 4.17113, 10.9228, | ||
207 | 10.0376, -27.4993, -8.25332, -1.715, -11.5063, -10.467, | ||
208 | 23.6637, -13.8338, 14.7284, 8.00341, -2.71881, -8.80708, | ||
209 | 27.101, 2.42801, 11.4599, -24.1577, -20.9901, 4.52358, | ||
210 | 16.8065, 19.3315, 11.1219, 13.3391, -13.1522, 0.91428, | ||
211 | -25.2603, 6.04837, 12.1994, 21.9372, 14.8795, 6.93368, | ||
212 | -1.24639, -7.96856, 16.4064, -2.36409, -25.9093, 46.0938, | ||
213 | 8.81687, 24.8004, 11.4475, -13.261, -19.8693, -28.4793, | ||
214 | 15.3175, -12.5335, 24.1778, 10.5133, 22.2244, 9.93191, | ||
215 | -18.7982, 38.939, -20.0631, -35.4052, 7.5879, -0.599373, | ||
216 | -18.1388, 9.5843, 17.4375, -21.057, 8.1634, 6.31216, | ||
217 | -61.5486, -8.71159, 19.7502, -25.2365, 3.56558, -1.64973, | ||
218 | -26.9863, 0.291017, -12.5337, -10.505, 11.0614, 4.84072, | ||
219 | -0.630579, -3.87056, -0.707795, -13.1306, -19.6548, -16.2436, | ||
220 | 4.87022, -5.90744, 3.46971, -40.0866, 16.8741, 10.3333, | ||
221 | -1.00985, 16.234, -0.475836, 28.3848, 1.75473, 28.2608 | ||
222 | }; | ||
223 | |||
224 | const struct lsp_codebook lspmelvq_cb[] = { | ||
225 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspmelvq1.txt */ | ||
226 | { | ||
227 | 6, | ||
228 | 6, | ||
229 | 64, | ||
230 | codes0 | ||
231 | }, | ||
232 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspmelvq2.txt */ | ||
233 | { | ||
234 | 6, | ||
235 | 6, | ||
236 | 64, | ||
237 | codes1 | ||
238 | }, | ||
239 | /* /Users/erdgeist/Coding/codec2/src/codebook/lspmelvq3.txt */ | ||
240 | { | ||
241 | 6, | ||
242 | 6, | ||
243 | 64, | ||
244 | codes2 | ||
245 | }, | ||
246 | { 0, 0, 0, 0 } | ||
247 | }; | ||
diff --git a/codebookmel.c b/codebookmel.c deleted file mode 100644 index a548db5..0000000 --- a/codebookmel.c +++ /dev/null | |||
@@ -1,145 +0,0 @@ | |||
1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ | ||
2 | |||
3 | /* | ||
4 | * This intermediary file and the files that used to create it are under | ||
5 | * The LGPL. See the file COPYING. | ||
6 | */ | ||
7 | |||
8 | #include "defines.h" | ||
9 | |||
10 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel1.txt */ | ||
11 | #ifdef __EMBEDDED__ | ||
12 | static const float codes0[] = { | ||
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
16 | 550, | ||
17 | 600, | ||
18 | 650, | ||
19 | 700, | ||
20 | 750, | ||
21 | 800, | ||
22 | 850, | ||
23 | 900 | ||
24 | }; | ||
25 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel2.txt */ | ||
26 | #ifdef __EMBEDDED__ | ||
27 | static const float codes1[] = { | ||
28 | #else | ||
29 | static float codes1[] = { | ||
30 | #endif | ||
31 | 50, | ||
32 | 100, | ||
33 | 200, | ||
34 | 300 | ||
35 | }; | ||
36 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel3.txt */ | ||
37 | #ifdef __EMBEDDED__ | ||
38 | static const float codes2[] = { | ||
39 | #else | ||
40 | static float codes2[] = { | ||
41 | #endif | ||
42 | 800, | ||
43 | 850, | ||
44 | 900, | ||
45 | 950, | ||
46 | 1000, | ||
47 | 1050, | ||
48 | 1100, | ||
49 | 1150, | ||
50 | 1200, | ||
51 | 1250, | ||
52 | 1300, | ||
53 | 1350, | ||
54 | 1400, | ||
55 | 1450, | ||
56 | 1500, | ||
57 | 1650 | ||
58 | }; | ||
59 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel4.txt */ | ||
60 | #ifdef __EMBEDDED__ | ||
61 | static const float codes3[] = { | ||
62 | #else | ||
63 | static float codes3[] = { | ||
64 | #endif | ||
65 | 25, | ||
66 | 50, | ||
67 | 75, | ||
68 | 100, | ||
69 | 125, | ||
70 | 150, | ||
71 | 175, | ||
72 | 250 | ||
73 | }; | ||
74 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel5.txt */ | ||
75 | #ifdef __EMBEDDED__ | ||
76 | static const float codes4[] = { | ||
77 | #else | ||
78 | static float codes4[] = { | ||
79 | #endif | ||
80 | 1350, | ||
81 | 1400, | ||
82 | 1450, | ||
83 | 1500, | ||
84 | 1550, | ||
85 | 1600, | ||
86 | 1650, | ||
87 | 1700 | ||
88 | }; | ||
89 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel6.txt */ | ||
90 | #ifdef __EMBEDDED__ | ||
91 | static const float codes5[] = { | ||
92 | #else | ||
93 | static float codes5[] = { | ||
94 | #endif | ||
95 | 25, | ||
96 | 50, | ||
97 | 100, | ||
98 | 150 | ||
99 | }; | ||
100 | |||
101 | const struct lsp_codebook mel_cb[] = { | ||
102 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel1.txt */ | ||
103 | { | ||
104 | 1, | ||
105 | 3, | ||
106 | 8, | ||
107 | codes0 | ||
108 | }, | ||
109 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel2.txt */ | ||
110 | { | ||
111 | 1, | ||
112 | 2, | ||
113 | 4, | ||
114 | codes1 | ||
115 | }, | ||
116 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel3.txt */ | ||
117 | { | ||
118 | 1, | ||
119 | 4, | ||
120 | 16, | ||
121 | codes2 | ||
122 | }, | ||
123 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel4.txt */ | ||
124 | { | ||
125 | 1, | ||
126 | 3, | ||
127 | 8, | ||
128 | codes3 | ||
129 | }, | ||
130 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel5.txt */ | ||
131 | { | ||
132 | 1, | ||
133 | 3, | ||
134 | 8, | ||
135 | codes4 | ||
136 | }, | ||
137 | /* /Users/erdgeist/Coding/codec2/src/codebook/mel6.txt */ | ||
138 | { | ||
139 | 1, | ||
140 | 2, | ||
141 | 4, | ||
142 | codes5 | ||
143 | }, | ||
144 | { 0, 0, 0, 0 } | ||
145 | }; | ||
diff --git a/codebooknewamp1.c b/codebooknewamp1.c index 6de33ee..4705acb 100644 --- a/codebooknewamp1.c +++ b/codebooknewamp1.c | |||
@@ -7,8 +7,12 @@ | |||
7 | 7 | ||
8 | #include "defines.h" | 8 | #include "defines.h" |
9 | 9 | ||
10 | /* /home/david/codec2-dev/src/codebook/train_120_1.txt */ | 10 | /* /Users/erdgeist/Coding/codec2/src/codebook/train_120_1.txt */ |
11 | #ifdef __EMBEDDED__ | ||
11 | static const float codes0[] = { | 12 | static const float codes0[] = { |
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
12 | 6.7484, 7.6125, 6.0332, 5.2789, 1.5239, 2.2353, 2.0748, 0.5289, 0.8748, 2.5432, -2.2863, -3.191, -0.0434, -1.9857, -3.3605, 0.7069, -5.9493, -0.5672, -0.6798, -18.0977, | 16 | 6.7484, 7.6125, 6.0332, 5.2789, 1.5239, 2.2353, 2.0748, 0.5289, 0.8748, 2.5432, -2.2863, -3.191, -0.0434, -1.9857, -3.3605, 0.7069, -5.9493, -0.5672, -0.6798, -18.0977, |
13 | 4.0503, 3.9086, 2.9225, 2.3773, 0.658, -0.4363, -0.0644, 2.4063, 1.3428, 2.4542, 0.5275, 0.982, -1.3277, 0.6811, 0.0273, -0.1838, -0.0222, -0.6478, -2.2405, -17.4152, | 17 | 4.0503, 3.9086, 2.9225, 2.3773, 0.658, -0.4363, -0.0644, 2.4063, 1.3428, 2.4542, 0.5275, 0.982, -1.3277, 0.6811, 0.0273, -0.1838, -0.0222, -0.6478, -2.2405, -17.4152, |
14 | 13.3284, 12.1212, 10.6531, 9.8214, 11.0388, 15.812, 19.711, 16.5488, 16.1068, 15.8771, 7.2553, 4.2486, -6.0036, -12.5476, -20.1299, -28.2803, -25.3971, -21.7907, -11.5143, -26.859, | 18 | 13.3284, 12.1212, 10.6531, 9.8214, 11.0388, 15.812, 19.711, 16.5488, 16.1068, 15.8771, 7.2553, 4.2486, -6.0036, -12.5476, -20.1299, -28.2803, -25.3971, -21.7907, -11.5143, -26.859, |
@@ -522,8 +526,12 @@ static const float codes0[] = { | |||
522 | 18.9039, 18.0327, 13.6297, 9.7561, 7.4319, 5.3744, 2.9646, 1.7415, 0.6716, 0.6859, 2.7446, 0.5342, -4.3187, -6.1877, -6.9311, -9.8734, -11.9041, -9.1281, -8.9591, -25.169, | 526 | 18.9039, 18.0327, 13.6297, 9.7561, 7.4319, 5.3744, 2.9646, 1.7415, 0.6716, 0.6859, 2.7446, 0.5342, -4.3187, -6.1877, -6.9311, -9.8734, -11.9041, -9.1281, -8.9591, -25.169, |
523 | 6.4513, 6.7843, 9.4438, 12.9549, 16.4801, 14.9093, 8.2954, 1.6877, -2.5193, -4.4922, -6.7348, -6.9853, -4.6783, 0.7181, 1.0483, -5.1128, -1.1161, -7.5305, -12.398, -27.2058 | 527 | 6.4513, 6.7843, 9.4438, 12.9549, 16.4801, 14.9093, 8.2954, 1.6877, -2.5193, -4.4922, -6.7348, -6.9853, -4.6783, 0.7181, 1.0483, -5.1128, -1.1161, -7.5305, -12.398, -27.2058 |
524 | }; | 528 | }; |
525 | /* /home/david/codec2-dev/src/codebook/train_120_2.txt */ | 529 | /* /Users/erdgeist/Coding/codec2/src/codebook/train_120_2.txt */ |
530 | #ifdef __EMBEDDED__ | ||
526 | static const float codes1[] = { | 531 | static const float codes1[] = { |
532 | #else | ||
533 | static float codes1[] = { | ||
534 | #endif | ||
527 | -1.2668, -1.2477, -0.0681, 3.8419, -0.0693, -1.7919, -1.5943, 0.8402, 0.155, -3.1526, -3.0204, 0.7337, -0.2603, 1.659, 0.023, 5.5893, -2.4959, 1.9604, -0.6348, 0.7999, | 535 | -1.2668, -1.2477, -0.0681, 3.8419, -0.0693, -1.7919, -1.5943, 0.8402, 0.155, -3.1526, -3.0204, 0.7337, -0.2603, 1.659, 0.023, 5.5893, -2.4959, 1.9604, -0.6348, 0.7999, |
528 | 2.6673, 1.4923, 1.1408, -0.7478, -1.0755, -1.3421, -0.4884, 0.2535, 0.2951, 1.5088, 1.9447, -2.662, 2.3751, 1.5298, 4.1357, -6.563, -2.1766, -2.7535, -0.7706, 1.2362, | 536 | 2.6673, 1.4923, 1.1408, -0.7478, -1.0755, -1.3421, -0.4884, 0.2535, 0.2951, 1.5088, 1.9447, -2.662, 2.3751, 1.5298, 4.1357, -6.563, -2.1766, -2.7535, -0.7706, 1.2362, |
529 | -0.6415, -0.4348, -1.2178, -0.987, -1.1057, -2.1421, -2.3594, -0.4977, -4.1484, -4.712, 5.5425, 3.0695, 3.661, 2.9729, 2.4379, -1.6136, -1.3052, 2.1342, 1.9164, -0.5692, | 537 | -0.6415, -0.4348, -1.2178, -0.987, -1.1057, -2.1421, -2.3594, -0.4977, -4.1484, -4.712, 5.5425, 3.0695, 3.661, 2.9729, 2.4379, -1.6136, -1.3052, 2.1342, 1.9164, -0.5692, |
@@ -1039,14 +1047,14 @@ static const float codes1[] = { | |||
1039 | }; | 1047 | }; |
1040 | 1048 | ||
1041 | const struct lsp_codebook newamp1vq_cb[] = { | 1049 | const struct lsp_codebook newamp1vq_cb[] = { |
1042 | /* /home/david/codec2-dev/src/codebook/train_120_1.txt */ | 1050 | /* /Users/erdgeist/Coding/codec2/src/codebook/train_120_1.txt */ |
1043 | { | 1051 | { |
1044 | 20, | 1052 | 20, |
1045 | 9, | 1053 | 9, |
1046 | 512, | 1054 | 512, |
1047 | codes0 | 1055 | codes0 |
1048 | }, | 1056 | }, |
1049 | /* /home/david/codec2-dev/src/codebook/train_120_2.txt */ | 1057 | /* /Users/erdgeist/Coding/codec2/src/codebook/train_120_2.txt */ |
1050 | { | 1058 | { |
1051 | 20, | 1059 | 20, |
1052 | 9, | 1060 | 9, |
diff --git a/codebooknewamp1_energy.c b/codebooknewamp1_energy.c index 6ecdd7c..7e6a092 100644 --- a/codebooknewamp1_energy.c +++ b/codebooknewamp1_energy.c | |||
@@ -7,8 +7,12 @@ | |||
7 | 7 | ||
8 | #include "defines.h" | 8 | #include "defines.h" |
9 | 9 | ||
10 | /* /home/david/codec2-dev/src/codebook/newamp1_energy_q.txt */ | 10 | /* /Users/erdgeist/Coding/codec2/src/codebook/newamp1_energy_q.txt */ |
11 | #ifdef __EMBEDDED__ | ||
11 | static const float codes0[] = { | 12 | static const float codes0[] = { |
13 | #else | ||
14 | static float codes0[] = { | ||
15 | #endif | ||
12 | 10, | 16 | 10, |
13 | 12.5, | 17 | 12.5, |
14 | 15, | 18 | 15, |
@@ -28,7 +32,7 @@ static const float codes0[] = { | |||
28 | }; | 32 | }; |
29 | 33 | ||
30 | const struct lsp_codebook newamp1_energy_cb[] = { | 34 | const struct lsp_codebook newamp1_energy_cb[] = { |
31 | /* /home/david/codec2-dev/src/codebook/newamp1_energy_q.txt */ | 35 | /* /Users/erdgeist/Coding/codec2/src/codebook/newamp1_energy_q.txt */ |
32 | { | 36 | { |
33 | 1, | 37 | 1, |
34 | 4, | 38 | 4, |
diff --git a/codebooknewamp2.c b/codebooknewamp2.c index c8389b0..f3e37dd 100644 --- a/codebooknewamp2.c +++ b/codebooknewamp2.c | |||
@@ -519,7 +519,7 @@ const struct lsp_codebook newamp2vq_cb[] = { | |||
519 | /* /Users/erdgeist/Coding/codec2/src/codebook/codes_450.txt */ | 519 | /* /Users/erdgeist/Coding/codec2/src/codebook/codes_450.txt */ |
520 | { | 520 | { |
521 | 41, | 521 | 41, |
522 | 8.96578, | 522 | 9, |
523 | 500, | 523 | 500, |
524 | codes0 | 524 | codes0 |
525 | }, | 525 | }, |
@@ -26,33 +26,31 @@ | |||
26 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 26 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include "codec2.h" | ||
30 | |||
29 | #include <assert.h> | 31 | #include <assert.h> |
32 | #include <math.h> | ||
33 | #include <stdbool.h> | ||
30 | #include <stdio.h> | 34 | #include <stdio.h> |
31 | #include <stdlib.h> | 35 | #include <stdlib.h> |
32 | #include <stdbool.h> | ||
33 | #include <string.h> | 36 | #include <string.h> |
34 | #include <math.h> | ||
35 | 37 | ||
36 | #include "defines.h" | 38 | #include "bpf.h" |
39 | #include "bpfb.h" | ||
37 | #include "codec2_fft.h" | 40 | #include "codec2_fft.h" |
38 | #include "sine.h" | 41 | #include "codec2_internal.h" |
39 | #include "nlp.h" | 42 | #include "debug_alloc.h" |
43 | #include "defines.h" | ||
40 | #include "dump.h" | 44 | #include "dump.h" |
41 | #include "lpc.h" | ||
42 | #include "quantise.h" | ||
43 | #include "phase.h" | ||
44 | #include "interp.h" | 45 | #include "interp.h" |
45 | #include "postfilter.h" | 46 | #include "lpc.h" |
46 | #include "codec2.h" | ||
47 | #include "lsp.h" | 47 | #include "lsp.h" |
48 | #include "newamp2.h" | ||
49 | #include "codec2_internal.h" | ||
50 | #include "machdep.h" | 48 | #include "machdep.h" |
51 | #include "bpf.h" | 49 | #include "nlp.h" |
52 | #include "bpfb.h" | 50 | #include "phase.h" |
53 | #include "c2wideband.h" | 51 | #include "postfilter.h" |
54 | 52 | #include "quantise.h" | |
55 | #include "debug_alloc.h" | 53 | #include "sine.h" |
56 | 54 | ||
57 | /*---------------------------------------------------------------------------* \ | 55 | /*---------------------------------------------------------------------------* \ |
58 | 56 | ||
@@ -62,32 +60,30 @@ | |||
62 | 60 | ||
63 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); | 61 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); |
64 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, | 62 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, |
65 | COMP Aw[], float gain); | 63 | COMP Aw[], float gain); |
66 | void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 64 | void codec2_encode_3200(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
67 | void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 65 | void codec2_decode_3200(struct CODEC2 *c2, short speech[], |
68 | void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 66 | const unsigned char *bits); |
69 | void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 67 | void codec2_encode_2400(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
70 | void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 68 | void codec2_decode_2400(struct CODEC2 *c2, short speech[], |
71 | void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 69 | const unsigned char *bits); |
72 | void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 70 | void codec2_encode_1600(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
73 | void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 71 | void codec2_decode_1600(struct CODEC2 *c2, short speech[], |
74 | void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 72 | const unsigned char *bits); |
75 | void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est); | 73 | void codec2_encode_1400(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
76 | void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 74 | void codec2_decode_1400(struct CODEC2 *c2, short speech[], |
77 | void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 75 | const unsigned char *bits); |
78 | void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 76 | void codec2_encode_1300(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
79 | void codec2_decode_700(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 77 | void codec2_decode_1300(struct CODEC2 *c2, short speech[], |
80 | void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 78 | const unsigned char *bits, float ber_est); |
81 | void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 79 | void codec2_encode_1200(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
82 | void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 80 | void codec2_decode_1200(struct CODEC2 *c2, short speech[], |
83 | void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 81 | const unsigned char *bits); |
84 | void codec2_encode_450(struct CODEC2 *c2, unsigned char * bits, short speech[]); | 82 | void codec2_encode_700c(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
85 | void codec2_decode_450(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 83 | void codec2_decode_700c(struct CODEC2 *c2, short speech[], |
86 | void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char * bits); | 84 | const unsigned char *bits); |
87 | static void ear_protection(float in_out[], int n); | 85 | static void ear_protection(float in_out[], int n); |
88 | 86 | ||
89 | |||
90 | |||
91 | /*---------------------------------------------------------------------------*\ | 87 | /*---------------------------------------------------------------------------*\ |
92 | 88 | ||
93 | FUNCTIONS | 89 | FUNCTIONS |
@@ -108,247 +104,170 @@ static void ear_protection(float in_out[], int n); | |||
108 | 104 | ||
109 | \*---------------------------------------------------------------------------*/ | 105 | \*---------------------------------------------------------------------------*/ |
110 | 106 | ||
111 | 107 | struct CODEC2 *codec2_create(int mode) { | |
112 | //Don't create CODEC2_MODE_450PWB for Encoding as it has undefined behavior ! | 108 | struct CODEC2 *c2; |
113 | struct CODEC2 * codec2_create(int mode) | 109 | int i, l; |
114 | { | 110 | |
115 | struct CODEC2 *c2; | 111 | // ALL POSSIBLE MODES MUST BE CHECKED HERE! |
116 | int i,l; | 112 | // we test if the desired mode is enabled at compile time |
117 | 113 | // and return NULL if not | |
118 | // ALL POSSIBLE MODES MUST BE CHECKED HERE! | 114 | |
119 | // we test if the desired mode is enabled at compile time | 115 | if (false == (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, mode) || |
120 | // and return NULL if not | 116 | CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, mode) || |
121 | 117 | CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, mode) || | |
122 | if (false == ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, mode) | 118 | CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, mode) || |
123 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, mode) | 119 | CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, mode) || |
124 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, mode) | 120 | CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, mode) || |
125 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, mode) | 121 | CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, mode))) { |
126 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, mode) | 122 | return NULL; |
127 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, mode) | 123 | } |
128 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_700, mode) | 124 | |
129 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, mode) | 125 | c2 = (struct CODEC2 *)MALLOC(sizeof(struct CODEC2)); |
130 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, mode) | 126 | if (c2 == NULL) return NULL; |
131 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_450, mode) | 127 | |
132 | || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) | 128 | c2->mode = mode; |
133 | ) ) | 129 | |
134 | { | 130 | /* store constants in a few places for convenience */ |
135 | return NULL; | 131 | |
136 | } | 132 | c2->c2const = c2const_create(8000, N_S); |
137 | 133 | c2->Fs = c2->c2const.Fs; | |
138 | c2 = (struct CODEC2*)MALLOC(sizeof(struct CODEC2)); | 134 | int n_samp = c2->n_samp = c2->c2const.n_samp; |
139 | if (c2 == NULL) | 135 | int m_pitch = c2->m_pitch = c2->c2const.m_pitch; |
140 | return NULL; | 136 | |
141 | 137 | c2->Pn = (float *)MALLOC(2 * n_samp * sizeof(float)); | |
142 | c2->mode = mode; | 138 | if (c2->Pn == NULL) { |
143 | 139 | return NULL; | |
144 | /* store constants in a few places for convenience */ | 140 | } |
145 | 141 | c2->Sn_ = (float *)MALLOC(2 * n_samp * sizeof(float)); | |
146 | if( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, mode) == 0){ | 142 | if (c2->Sn_ == NULL) { |
147 | c2->c2const = c2const_create(8000, N_S); | 143 | FREE(c2->Pn); |
148 | }else{ | 144 | return NULL; |
149 | c2->c2const = c2const_create(16000, N_S); | 145 | } |
150 | } | 146 | c2->w = (float *)MALLOC(m_pitch * sizeof(float)); |
151 | c2->Fs = c2->c2const.Fs; | 147 | if (c2->w == NULL) { |
152 | int n_samp = c2->n_samp = c2->c2const.n_samp; | 148 | FREE(c2->Pn); |
153 | int m_pitch = c2->m_pitch = c2->c2const.m_pitch; | 149 | FREE(c2->Sn_); |
154 | 150 | return NULL; | |
155 | c2->Pn = (float*)MALLOC(2*n_samp*sizeof(float)); | 151 | } |
156 | if (c2->Pn == NULL) { | 152 | c2->Sn = (float *)MALLOC(m_pitch * sizeof(float)); |
157 | return NULL; | 153 | if (c2->Sn == NULL) { |
158 | } | 154 | FREE(c2->Pn); |
159 | c2->Sn_ = (float*)MALLOC(2*n_samp*sizeof(float)); | 155 | FREE(c2->Sn_); |
160 | if (c2->Sn_ == NULL) { | 156 | FREE(c2->w); |
161 | FREE(c2->Pn); | 157 | return NULL; |
162 | return NULL; | 158 | } |
163 | } | 159 | |
164 | c2->w = (float*)MALLOC(m_pitch*sizeof(float)); | 160 | for (i = 0; i < m_pitch; i++) c2->Sn[i] = 1.0; |
165 | if (c2->w == NULL) { | 161 | c2->hpf_states[0] = c2->hpf_states[1] = 0.0; |
166 | FREE(c2->Pn); | 162 | for (i = 0; i < 2 * n_samp; i++) c2->Sn_[i] = 0; |
167 | FREE(c2->Sn_); | 163 | c2->fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); |
168 | return NULL; | 164 | c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); |
169 | } | 165 | make_analysis_window(&c2->c2const, c2->fft_fwd_cfg, c2->w, c2->W); |
170 | c2->Sn = (float*)MALLOC(m_pitch*sizeof(float)); | 166 | make_synthesis_window(&c2->c2const, c2->Pn); |
171 | if (c2->Sn == NULL) { | 167 | c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); |
172 | FREE(c2->Pn); | 168 | c2->prev_f0_enc = 1 / P_MAX_S; |
173 | FREE(c2->Sn_); | 169 | c2->bg_est = 0.0; |
174 | FREE(c2->w); | 170 | c2->ex_phase = 0.0; |
175 | return NULL; | 171 | |
176 | } | 172 | for (l = 1; l <= MAX_AMP; l++) c2->prev_model_dec.A[l] = 0.0; |
177 | 173 | c2->prev_model_dec.Wo = TWO_PI / c2->c2const.p_max; | |
178 | for(i=0; i<m_pitch; i++) | 174 | c2->prev_model_dec.L = PI / c2->prev_model_dec.Wo; |
179 | c2->Sn[i] = 1.0; | 175 | c2->prev_model_dec.voiced = 0; |
180 | c2->hpf_states[0] = c2->hpf_states[1] = 0.0; | 176 | |
181 | for(i=0; i<2*n_samp; i++) | 177 | for (i = 0; i < LPC_ORD; i++) { |
182 | c2->Sn_[i] = 0; | 178 | c2->prev_lsps_dec[i] = i * PI / (LPC_ORD + 1); |
183 | c2->fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); | 179 | } |
184 | c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); | 180 | c2->prev_e_dec = 1; |
185 | make_analysis_window(&c2->c2const, c2->fft_fwd_cfg, c2->w,c2->W); | 181 | |
186 | make_synthesis_window(&c2->c2const, c2->Pn); | 182 | c2->nlp = nlp_create(&c2->c2const); |
187 | c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); | 183 | if (c2->nlp == NULL) { |
188 | quantise_init(); | 184 | return NULL; |
189 | c2->prev_f0_enc = 1/P_MAX_S; | 185 | } |
190 | c2->bg_est = 0.0; | 186 | |
191 | c2->ex_phase = 0.0; | 187 | c2->lpc_pf = 1; |
192 | 188 | c2->bass_boost = 1; | |
193 | for(l=1; l<=MAX_AMP; l++) | 189 | c2->beta = LPCPF_BETA; |
194 | c2->prev_model_dec.A[l] = 0.0; | 190 | c2->gamma = LPCPF_GAMMA; |
195 | c2->prev_model_dec.Wo = TWO_PI/c2->c2const.p_max; | 191 | |
196 | c2->prev_model_dec.L = PI/c2->prev_model_dec.Wo; | 192 | c2->xq_enc[0] = c2->xq_enc[1] = 0.0; |
197 | c2->prev_model_dec.voiced = 0; | 193 | c2->xq_dec[0] = c2->xq_dec[1] = 0.0; |
198 | 194 | ||
199 | for(i=0; i<LPC_ORD; i++) { | 195 | c2->smoothing = 0; |
200 | c2->prev_lsps_dec[i] = i*PI/(LPC_ORD+1); | 196 | c2->se = 0.0; |
201 | } | 197 | c2->nse = 0; |
202 | c2->prev_e_dec = 1; | 198 | c2->user_rate_K_vec_no_mean_ = NULL; |
203 | 199 | c2->post_filter_en = true; | |
204 | c2->nlp = nlp_create(&c2->c2const); | 200 | |
205 | if (c2->nlp == NULL) { | 201 | c2->bpf_buf = (float *)MALLOC(sizeof(float) * (BPF_N + 4 * c2->n_samp)); |
206 | return NULL; | 202 | assert(c2->bpf_buf != NULL); |
207 | } | 203 | for (i = 0; i < BPF_N + 4 * c2->n_samp; i++) c2->bpf_buf[i] = 0.0; |
208 | 204 | ||
209 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, mode)) | 205 | c2->softdec = NULL; |
210 | c2->gray = 0; // natural binary better for trellis decoding (hopefully added later) | 206 | c2->gray = 1; |
211 | else | 207 | |
212 | c2->gray = 1; | 208 | /* newamp1 initialisation */ |
213 | 209 | ||
214 | c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma = LPCPF_GAMMA; | 210 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { |
215 | 211 | mel_sample_freqs_kHz(c2->rate_K_sample_freqs_kHz, NEWAMP1_K, ftomel(200.0), | |
216 | c2->xq_enc[0] = c2->xq_enc[1] = 0.0; | 212 | ftomel(3700.0)); |
217 | c2->xq_dec[0] = c2->xq_dec[1] = 0.0; | 213 | int k; |
218 | 214 | for (k = 0; k < NEWAMP1_K; k++) { | |
219 | c2->smoothing = 0; | 215 | c2->prev_rate_K_vec_[k] = 0.0; |
220 | c2->se = 0.0; c2->nse = 0; | 216 | c2->eq[k] = 0.0; |
221 | c2->user_rate_K_vec_no_mean_ = NULL; | 217 | } |
222 | c2->post_filter_en = 1; | 218 | c2->eq_en = false; |
223 | 219 | c2->Wo_left = 0.0; | |
224 | c2->bpf_buf = (float*)MALLOC(sizeof(float)*(BPF_N+4*c2->n_samp)); | 220 | c2->voicing_left = 0; |
225 | assert(c2->bpf_buf != NULL); | 221 | c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL); |
226 | for(i=0; i<BPF_N+4*c2->n_samp; i++) | 222 | c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL); |
227 | c2->bpf_buf[i] = 0.0; | 223 | } |
228 | 224 | ||
229 | c2->softdec = NULL; | 225 | c2->fmlfeat = NULL; |
230 | 226 | c2->fmlmodel = NULL; | |
231 | /* newamp1 initialisation */ | 227 | |
232 | 228 | // make sure that one of the two decode function pointers is empty | |
233 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { | 229 | // for the encode function pointer this is not required since we always set it |
234 | mel_sample_freqs_kHz(c2->rate_K_sample_freqs_kHz, NEWAMP1_K, ftomel(200.0), ftomel(3700.0) ); | 230 | // to a meaningful value |
235 | int k; | 231 | |
236 | for(k=0; k<NEWAMP1_K; k++) { | 232 | c2->decode = NULL; |
237 | c2->prev_rate_K_vec_[k] = 0.0; | 233 | c2->decode_ber = NULL; |
238 | c2->eq[k] = 0.0; | 234 | |
239 | } | 235 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) { |
240 | c2->eq_en = 0; | 236 | c2->encode = codec2_encode_3200; |
241 | c2->Wo_left = 0.0; | 237 | c2->decode = codec2_decode_3200; |
242 | c2->voicing_left = 0;; | 238 | } |
243 | c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL); | 239 | |
244 | c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL); | 240 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) { |
245 | } | 241 | c2->encode = codec2_encode_2400; |
246 | 242 | c2->decode = codec2_decode_2400; | |
247 | /* newamp2 initialisation */ | 243 | } |
248 | 244 | ||
249 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { | 245 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) { |
250 | n2_mel_sample_freqs_kHz(c2->n2_rate_K_sample_freqs_kHz, NEWAMP2_K); | 246 | c2->encode = codec2_encode_1600; |
251 | int k; | 247 | c2->decode = codec2_decode_1600; |
252 | for(k=0; k<NEWAMP2_K; k++) { | 248 | } |
253 | c2->n2_prev_rate_K_vec_[k] = 0.0; | 249 | |
254 | } | 250 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) { |
255 | c2->Wo_left = 0.0; | 251 | c2->encode = codec2_encode_1400; |
256 | c2->voicing_left = 0;; | 252 | c2->decode = codec2_decode_1400; |
257 | c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP2_PHASE_NFFT, 0, NULL, NULL); | 253 | } |
258 | c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP2_PHASE_NFFT, 1, NULL, NULL); | 254 | |
259 | } | 255 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) { |
260 | /* newamp2 PWB initialisation */ | 256 | c2->encode = codec2_encode_1300; |
261 | 257 | c2->decode_ber = codec2_decode_1300; | |
262 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { | 258 | } |
263 | n2_mel_sample_freqs_kHz(c2->n2_pwb_rate_K_sample_freqs_kHz, NEWAMP2_16K_K); | 259 | |
264 | int k; | 260 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) { |
265 | for(k=0; k<NEWAMP2_16K_K; k++) { | 261 | c2->encode = codec2_encode_1200; |
266 | c2->n2_pwb_prev_rate_K_vec_[k] = 0.0; | 262 | c2->decode = codec2_decode_1200; |
267 | } | 263 | } |
268 | c2->Wo_left = 0.0; | 264 | |
269 | c2->voicing_left = 0;; | 265 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { |
270 | c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP2_PHASE_NFFT, 0, NULL, NULL); | 266 | c2->encode = codec2_encode_700c; |
271 | c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP2_PHASE_NFFT, 1, NULL, NULL); | 267 | c2->decode = codec2_decode_700c; |
272 | } | 268 | } |
273 | 269 | ||
274 | c2->fmlfeat = NULL; | 270 | return c2; |
275 | |||
276 | // make sure that one of the two decode function pointers is empty | ||
277 | // for the encode function pointer this is not required since we always set it | ||
278 | // to a meaningful value | ||
279 | |||
280 | c2->decode = NULL; | ||
281 | c2->decode_ber = NULL; | ||
282 | |||
283 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) | ||
284 | { | ||
285 | c2->encode = codec2_encode_3200; | ||
286 | c2->decode = codec2_decode_3200; | ||
287 | } | ||
288 | |||
289 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) | ||
290 | { | ||
291 | c2->encode = codec2_encode_2400; | ||
292 | c2->decode = codec2_decode_2400; | ||
293 | } | ||
294 | |||
295 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) | ||
296 | { | ||
297 | c2->encode = codec2_encode_1600; | ||
298 | c2->decode = codec2_decode_1600; | ||
299 | } | ||
300 | |||
301 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) | ||
302 | { | ||
303 | c2->encode = codec2_encode_1400; | ||
304 | c2->decode = codec2_decode_1400; | ||
305 | } | ||
306 | |||
307 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) | ||
308 | { | ||
309 | c2->encode = codec2_encode_1300; | ||
310 | c2->decode_ber = codec2_decode_1300; | ||
311 | } | ||
312 | |||
313 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) | ||
314 | { | ||
315 | c2->encode = codec2_encode_1200; | ||
316 | c2->decode = codec2_decode_1200; | ||
317 | } | ||
318 | |||
319 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700, c2->mode)) | ||
320 | { | ||
321 | c2->encode = codec2_encode_700; | ||
322 | c2->decode = codec2_decode_700; | ||
323 | } | ||
324 | |||
325 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, c2->mode)) | ||
326 | { | ||
327 | c2->encode = codec2_encode_700b; | ||
328 | c2->decode = codec2_decode_700b; | ||
329 | } | ||
330 | |||
331 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) | ||
332 | { | ||
333 | c2->encode = codec2_encode_700c; | ||
334 | c2->decode = codec2_decode_700c; | ||
335 | } | ||
336 | |||
337 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) | ||
338 | { | ||
339 | c2->encode = codec2_encode_450; | ||
340 | c2->decode = codec2_decode_450; | ||
341 | } | ||
342 | |||
343 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) | ||
344 | { | ||
345 | //Encode PWB doesnt make sense | ||
346 | c2->encode = codec2_encode_450; | ||
347 | c2->decode = codec2_decode_450pwb; | ||
348 | } | ||
349 | |||
350 | |||
351 | return c2; | ||
352 | } | 271 | } |
353 | 272 | ||
354 | /*---------------------------------------------------------------------------*\ | 273 | /*---------------------------------------------------------------------------*\ |
@@ -361,31 +280,22 @@ struct CODEC2 * codec2_create(int mode) | |||
361 | 280 | ||
362 | \*---------------------------------------------------------------------------*/ | 281 | \*---------------------------------------------------------------------------*/ |
363 | 282 | ||
364 | void codec2_destroy(struct CODEC2 *c2) | 283 | void codec2_destroy(struct CODEC2 *c2) { |
365 | { | 284 | assert(c2 != NULL); |
366 | assert(c2 != NULL); | 285 | FREE(c2->bpf_buf); |
367 | FREE(c2->bpf_buf); | 286 | nlp_destroy(c2->nlp); |
368 | nlp_destroy(c2->nlp); | 287 | codec2_fft_free(c2->fft_fwd_cfg); |
369 | codec2_fft_free(c2->fft_fwd_cfg); | 288 | codec2_fftr_free(c2->fftr_fwd_cfg); |
370 | codec2_fftr_free(c2->fftr_fwd_cfg); | 289 | codec2_fftr_free(c2->fftr_inv_cfg); |
371 | codec2_fftr_free(c2->fftr_inv_cfg); | 290 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { |
372 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { | 291 | codec2_fft_free(c2->phase_fft_fwd_cfg); |
373 | codec2_fft_free(c2->phase_fft_fwd_cfg); | 292 | codec2_fft_free(c2->phase_fft_inv_cfg); |
374 | codec2_fft_free(c2->phase_fft_inv_cfg); | 293 | } |
375 | } | 294 | FREE(c2->Pn); |
376 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) { | 295 | FREE(c2->Sn); |
377 | codec2_fft_free(c2->phase_fft_fwd_cfg); | 296 | FREE(c2->w); |
378 | codec2_fft_free(c2->phase_fft_inv_cfg); | 297 | FREE(c2->Sn_); |
379 | } | 298 | FREE(c2); |
380 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { | ||
381 | codec2_fft_free(c2->phase_fft_fwd_cfg); | ||
382 | codec2_fft_free(c2->phase_fft_inv_cfg); | ||
383 | } | ||
384 | FREE(c2->Pn); | ||
385 | FREE(c2->Sn); | ||
386 | FREE(c2->w); | ||
387 | FREE(c2->Sn_); | ||
388 | FREE(c2); | ||
389 | } | 299 | } |
390 | 300 | ||
391 | /*---------------------------------------------------------------------------*\ | 301 | /*---------------------------------------------------------------------------*\ |
@@ -399,32 +309,31 @@ void codec2_destroy(struct CODEC2 *c2) | |||
399 | \*---------------------------------------------------------------------------*/ | 309 | \*---------------------------------------------------------------------------*/ |
400 | 310 | ||
401 | int codec2_bits_per_frame(struct CODEC2 *c2) { | 311 | int codec2_bits_per_frame(struct CODEC2 *c2) { |
402 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) | 312 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) return 64; |
403 | return 64; | 313 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) return 48; |
404 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) | 314 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) return 64; |
405 | return 48; | 315 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) return 56; |
406 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) | 316 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) return 52; |
407 | return 64; | 317 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) return 48; |
408 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) | 318 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) return 28; |
409 | return 56; | 319 | |
410 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) | 320 | return 0; /* shouldn't get here */ |
411 | return 52; | ||
412 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) | ||
413 | return 48; | ||
414 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700, c2->mode)) | ||
415 | return 28; | ||
416 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, c2->mode)) | ||
417 | return 28; | ||
418 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) | ||
419 | return 28; | ||
420 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) | ||
421 | return 18; | ||
422 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) | ||
423 | return 18; | ||
424 | |||
425 | return 0; /* shouldn't get here */ | ||
426 | } | 321 | } |
427 | 322 | ||
323 | /*---------------------------------------------------------------------------*\ | ||
324 | |||
325 | FUNCTION....: codec2_bytes_per_frame | ||
326 | DATE CREATED: April 2021 | ||
327 | |||
328 | Returns the number of bytes per frame. Useful for allocated storage for | ||
329 | codec2_encode()/codec2_decode(). Note the number of bits may not be a | ||
330 | multiple of 8, therefore some bits in the last byte may be unused. | ||
331 | |||
332 | \*---------------------------------------------------------------------------*/ | ||
333 | |||
334 | int codec2_bytes_per_frame(struct CODEC2 *c2) { | ||
335 | return (codec2_bits_per_frame(c2) + 7) / 8; | ||
336 | } | ||
428 | 337 | ||
429 | /*---------------------------------------------------------------------------*\ | 338 | /*---------------------------------------------------------------------------*\ |
430 | 339 | ||
@@ -437,60 +346,61 @@ int codec2_bits_per_frame(struct CODEC2 *c2) { | |||
437 | \*---------------------------------------------------------------------------*/ | 346 | \*---------------------------------------------------------------------------*/ |
438 | 347 | ||
439 | int codec2_samples_per_frame(struct CODEC2 *c2) { | 348 | int codec2_samples_per_frame(struct CODEC2 *c2) { |
440 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) | 349 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) return 160; |
441 | return 160; | 350 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) return 160; |
442 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) | 351 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) return 320; |
443 | return 160; | 352 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) return 320; |
444 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) | 353 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) return 320; |
445 | return 320; | 354 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) return 320; |
446 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) | 355 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) return 320; |
447 | return 320; | 356 | return 0; /* shouldn't get here */ |
448 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) | ||
449 | return 320; | ||
450 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) | ||
451 | return 320; | ||
452 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700, c2->mode)) | ||
453 | return 320; | ||
454 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, c2->mode)) | ||
455 | return 320; | ||
456 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) | ||
457 | return 320; | ||
458 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) | ||
459 | return 320; | ||
460 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) | ||
461 | return 640; | ||
462 | return 0; /* shouldnt get here */ | ||
463 | } | 357 | } |
464 | 358 | ||
465 | void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[]) | 359 | /*---------------------------------------------------------------------------*\ |
466 | { | 360 | |
467 | assert(c2 != NULL); | 361 | FUNCTION....: codec2_encode |
468 | assert(c2->encode != NULL); | 362 | AUTHOR......: David Rowe |
363 | DATE CREATED: Nov 14 2011 | ||
364 | |||
365 | Take an input buffer of speech samples, and compress them to a packed buffer | ||
366 | of bytes. | ||
469 | 367 | ||
470 | c2->encode(c2, bits, speech); | 368 | \*---------------------------------------------------------------------------*/ |
471 | 369 | ||
472 | } | 370 | void codec2_encode(struct CODEC2 *c2, unsigned char *bytes, short speech[]) { |
371 | assert(c2 != NULL); | ||
372 | assert(c2->encode != NULL); | ||
473 | 373 | ||
474 | void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits) | 374 | c2->encode(c2, bytes, speech); |
475 | { | ||
476 | codec2_decode_ber(c2, speech, bits, 0.0); | ||
477 | } | 375 | } |
478 | 376 | ||
479 | void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *bits, float ber_est) | 377 | /*---------------------------------------------------------------------------*\ |
480 | { | ||
481 | assert(c2 != NULL); | ||
482 | assert(c2->decode != NULL || c2->decode_ber != NULL); | ||
483 | 378 | ||
484 | if (c2->decode != NULL) | 379 | FUNCTION....: codec2_decode |
485 | { | 380 | AUTHOR......: David Rowe |
486 | c2->decode(c2, speech, bits); | 381 | DATE CREATED: Nov 14 2011 |
487 | } | 382 | |
488 | else | 383 | Take an input packed buffer of bytes, and decode them to a buffer of speech |
489 | { | 384 | samples. |
490 | c2->decode_ber(c2, speech, bits, ber_est); | 385 | |
491 | } | 386 | \*---------------------------------------------------------------------------*/ |
387 | |||
388 | void codec2_decode(struct CODEC2 *c2, short speech[], | ||
389 | const unsigned char *bytes) { | ||
390 | codec2_decode_ber(c2, speech, bytes, 0.0); | ||
492 | } | 391 | } |
493 | 392 | ||
393 | void codec2_decode_ber(struct CODEC2 *c2, short speech[], | ||
394 | const unsigned char *bits, float ber_est) { | ||
395 | assert(c2 != NULL); | ||
396 | assert(c2->decode != NULL || c2->decode_ber != NULL); | ||
397 | |||
398 | if (c2->decode != NULL) { | ||
399 | c2->decode(c2, speech, bits); | ||
400 | } else { | ||
401 | c2->decode_ber(c2, speech, bits, ber_est); | ||
402 | } | ||
403 | } | ||
494 | 404 | ||
495 | /*---------------------------------------------------------------------------*\ | 405 | /*---------------------------------------------------------------------------*\ |
496 | 406 | ||
@@ -503,60 +413,60 @@ void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *b | |||
503 | The codec2 algorithm actually operates internally on 10ms (80 | 413 | The codec2 algorithm actually operates internally on 10ms (80 |
504 | sample) frames, so we run the encoding algorithm twice. On the | 414 | sample) frames, so we run the encoding algorithm twice. On the |
505 | first frame we just send the voicing bits. On the second frame we | 415 | first frame we just send the voicing bits. On the second frame we |
506 | send all model parameters. Compared to 2400 we use a larger number | 416 | send all model parameters. Compared to 2400 we encode the LSP |
507 | of bits for the LSPs and non-VQ pitch and energy. | 417 | differences, a larger number of bits for the LSP(d)s and scalar |
418 | (non-VQ) quantisation for pitch and energy. | ||
508 | 419 | ||
509 | The bit allocation is: | 420 | The bit allocation is: |
510 | 421 | ||
511 | Parameter bits/frame | 422 | Parameter bits/frame |
512 | -------------------------------------- | 423 | ------------------------------------------------------ |
513 | Harmonic magnitudes (LSPs) 50 | 424 | Harmonic magnitudes (LSP differerences) 50 |
514 | Pitch (Wo) 7 | 425 | Pitch (Wo) 7 |
515 | Energy 5 | 426 | Energy 5 |
516 | Voicing (10ms update) 2 | 427 | Voicing (10ms update) 2 |
517 | TOTAL 64 | 428 | TOTAL 64 |
518 | 429 | ||
519 | \*---------------------------------------------------------------------------*/ | 430 | \*---------------------------------------------------------------------------*/ |
520 | 431 | ||
521 | void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 432 | void codec2_encode_3200(struct CODEC2 *c2, unsigned char *bits, |
522 | { | 433 | short speech[]) { |
523 | MODEL model; | 434 | MODEL model; |
524 | float ak[LPC_ORD+1]; | 435 | float ak[LPC_ORD + 1]; |
525 | float lsps[LPC_ORD]; | 436 | float lsps[LPC_ORD]; |
526 | float e; | 437 | float e; |
527 | int Wo_index, e_index; | 438 | int Wo_index, e_index; |
528 | int lspd_indexes[LPC_ORD]; | 439 | int lspd_indexes[LPC_ORD]; |
529 | int i; | 440 | int i; |
530 | unsigned int nbit = 0; | 441 | unsigned int nbit = 0; |
531 | 442 | ||
532 | assert(c2 != NULL); | 443 | assert(c2 != NULL); |
533 | 444 | ||
534 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 445 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
535 | 446 | ||
536 | /* first 10ms analysis frame - we just want voicing */ | 447 | /* first 10ms analysis frame - we just want voicing */ |
537 | 448 | ||
538 | analyse_one_frame(c2, &model, speech); | 449 | analyse_one_frame(c2, &model, speech); |
539 | pack(bits, &nbit, model.voiced, 1); | 450 | pack(bits, &nbit, model.voiced, 1); |
540 | 451 | ||
541 | /* second 10ms analysis frame */ | 452 | /* second 10ms analysis frame */ |
542 | 453 | ||
543 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); | 454 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); |
544 | pack(bits, &nbit, model.voiced, 1); | 455 | pack(bits, &nbit, model.voiced, 1); |
545 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); | 456 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); |
546 | pack(bits, &nbit, Wo_index, WO_BITS); | 457 | pack(bits, &nbit, Wo_index, WO_BITS); |
547 | 458 | ||
548 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 459 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
549 | e_index = encode_energy(e, E_BITS); | 460 | e_index = encode_energy(e, E_BITS); |
550 | pack(bits, &nbit, e_index, E_BITS); | 461 | pack(bits, &nbit, e_index, E_BITS); |
551 | 462 | ||
552 | encode_lspds_scalar(lspd_indexes, lsps, LPC_ORD); | 463 | encode_lspds_scalar(lspd_indexes, lsps, LPC_ORD); |
553 | for(i=0; i<LSPD_SCALAR_INDEXES; i++) { | 464 | for (i = 0; i < LSPD_SCALAR_INDEXES; i++) { |
554 | pack(bits, &nbit, lspd_indexes[i], lspd_bits(i)); | 465 | pack(bits, &nbit, lspd_indexes[i], lspd_bits(i)); |
555 | } | 466 | } |
556 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 467 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); |
557 | } | 468 | } |
558 | 469 | ||
559 | |||
560 | /*---------------------------------------------------------------------------*\ | 470 | /*---------------------------------------------------------------------------*\ |
561 | 471 | ||
562 | FUNCTION....: codec2_decode_3200 | 472 | FUNCTION....: codec2_decode_3200 |
@@ -567,77 +477,75 @@ void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
567 | 477 | ||
568 | \*---------------------------------------------------------------------------*/ | 478 | \*---------------------------------------------------------------------------*/ |
569 | 479 | ||
570 | void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 480 | void codec2_decode_3200(struct CODEC2 *c2, short speech[], |
571 | { | 481 | const unsigned char *bits) { |
572 | MODEL model[2]; | 482 | MODEL model[2]; |
573 | int lspd_indexes[LPC_ORD]; | 483 | int lspd_indexes[LPC_ORD]; |
574 | float lsps[2][LPC_ORD]; | 484 | float lsps[2][LPC_ORD]; |
575 | int Wo_index, e_index; | 485 | int Wo_index, e_index; |
576 | float e[2]; | 486 | float e[2]; |
577 | float snr; | 487 | float snr; |
578 | float ak[2][LPC_ORD+1]; | 488 | float ak[2][LPC_ORD + 1]; |
579 | int i,j; | 489 | int i, j; |
580 | unsigned int nbit = 0; | 490 | unsigned int nbit = 0; |
581 | COMP Aw[FFT_ENC]; | 491 | COMP Aw[FFT_ENC]; |
582 | 492 | ||
583 | assert(c2 != NULL); | 493 | assert(c2 != NULL); |
584 | 494 | ||
585 | /* only need to zero these out due to (unused) snr calculation */ | 495 | /* only need to zero these out due to (unused) snr calculation */ |
586 | 496 | ||
587 | for(i=0; i<2; i++) | 497 | for (i = 0; i < 2; i++) |
588 | for(j=1; j<=MAX_AMP; j++) | 498 | for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; |
589 | model[i].A[j] = 0.0; | ||
590 | 499 | ||
591 | /* unpack bits from channel ------------------------------------*/ | 500 | /* unpack bits from channel ------------------------------------*/ |
592 | 501 | ||
593 | /* this will partially fill the model params for the 2 x 10ms | 502 | /* this will partially fill the model params for the 2 x 10ms |
594 | frames */ | 503 | frames */ |
595 | 504 | ||
596 | model[0].voiced = unpack(bits, &nbit, 1); | 505 | model[0].voiced = unpack(bits, &nbit, 1); |
597 | model[1].voiced = unpack(bits, &nbit, 1); | 506 | model[1].voiced = unpack(bits, &nbit, 1); |
598 | 507 | ||
599 | Wo_index = unpack(bits, &nbit, WO_BITS); | 508 | Wo_index = unpack(bits, &nbit, WO_BITS); |
600 | model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); | 509 | model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); |
601 | model[1].L = PI/model[1].Wo; | 510 | model[1].L = PI / model[1].Wo; |
602 | 511 | ||
603 | e_index = unpack(bits, &nbit, E_BITS); | 512 | e_index = unpack(bits, &nbit, E_BITS); |
604 | e[1] = decode_energy(e_index, E_BITS); | 513 | e[1] = decode_energy(e_index, E_BITS); |
605 | 514 | ||
606 | for(i=0; i<LSPD_SCALAR_INDEXES; i++) { | 515 | for (i = 0; i < LSPD_SCALAR_INDEXES; i++) { |
607 | lspd_indexes[i] = unpack(bits, &nbit, lspd_bits(i)); | 516 | lspd_indexes[i] = unpack(bits, &nbit, lspd_bits(i)); |
608 | } | 517 | } |
609 | decode_lspds_scalar(&lsps[1][0], lspd_indexes, LPC_ORD); | 518 | decode_lspds_scalar(&lsps[1][0], lspd_indexes, LPC_ORD); |
610 | 519 | ||
611 | /* interpolate ------------------------------------------------*/ | 520 | /* interpolate ------------------------------------------------*/ |
612 | 521 | ||
613 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | 522 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 |
614 | 10ms frame between 20ms samples */ | 523 | 10ms frame between 20ms samples */ |
615 | 524 | ||
616 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | 525 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); |
617 | e[0] = interp_energy(c2->prev_e_dec, e[1]); | 526 | e[0] = interp_energy(c2->prev_e_dec, e[1]); |
618 | 527 | ||
619 | /* LSPs are sampled every 20ms so we interpolate the frame in | 528 | /* LSPs are sampled every 20ms so we interpolate the frame in |
620 | between, then recover spectral amplitudes */ | 529 | between, then recover spectral amplitudes */ |
621 | 530 | ||
622 | interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, LPC_ORD); | 531 | interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, |
532 | LPC_ORD); | ||
623 | 533 | ||
624 | for(i=0; i<2; i++) { | 534 | for (i = 0; i < 2; i++) { |
625 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | 535 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); |
626 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | 536 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, |
627 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | 537 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); |
628 | apply_lpc_correction(&model[i]); | 538 | apply_lpc_correction(&model[i]); |
629 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | 539 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], Aw, 1.0); |
630 | } | 540 | } |
631 | 541 | ||
632 | /* update memories for next frame ----------------------------*/ | 542 | /* update memories for next frame ----------------------------*/ |
633 | 543 | ||
634 | c2->prev_model_dec = model[1]; | 544 | c2->prev_model_dec = model[1]; |
635 | c2->prev_e_dec = e[1]; | 545 | c2->prev_e_dec = e[1]; |
636 | for(i=0; i<LPC_ORD; i++) | 546 | for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[1][i]; |
637 | c2->prev_lsps_dec[i] = lsps[1][i]; | ||
638 | } | 547 | } |
639 | 548 | ||
640 | |||
641 | /*---------------------------------------------------------------------------*\ | 549 | /*---------------------------------------------------------------------------*\ |
642 | 550 | ||
643 | FUNCTION....: codec2_encode_2400 | 551 | FUNCTION....: codec2_encode_2400 |
@@ -663,46 +571,45 @@ void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * | |||
663 | 571 | ||
664 | \*---------------------------------------------------------------------------*/ | 572 | \*---------------------------------------------------------------------------*/ |
665 | 573 | ||
666 | void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 574 | void codec2_encode_2400(struct CODEC2 *c2, unsigned char *bits, |
667 | { | 575 | short speech[]) { |
668 | MODEL model; | 576 | MODEL model; |
669 | float ak[LPC_ORD+1]; | 577 | float ak[LPC_ORD + 1]; |
670 | float lsps[LPC_ORD]; | 578 | float lsps[LPC_ORD]; |
671 | float e; | 579 | float e; |
672 | int WoE_index; | 580 | int WoE_index; |
673 | int lsp_indexes[LPC_ORD]; | 581 | int lsp_indexes[LPC_ORD]; |
674 | int i; | 582 | int i; |
675 | int spare = 0; | 583 | int spare = 0; |
676 | unsigned int nbit = 0; | 584 | unsigned int nbit = 0; |
677 | 585 | ||
678 | assert(c2 != NULL); | 586 | assert(c2 != NULL); |
679 | 587 | ||
680 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 588 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
681 | 589 | ||
682 | /* first 10ms analysis frame - we just want voicing */ | 590 | /* first 10ms analysis frame - we just want voicing */ |
683 | 591 | ||
684 | analyse_one_frame(c2, &model, speech); | 592 | analyse_one_frame(c2, &model, speech); |
685 | pack(bits, &nbit, model.voiced, 1); | 593 | pack(bits, &nbit, model.voiced, 1); |
686 | 594 | ||
687 | /* second 10ms analysis frame */ | 595 | /* second 10ms analysis frame */ |
688 | 596 | ||
689 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); | 597 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); |
690 | pack(bits, &nbit, model.voiced, 1); | 598 | pack(bits, &nbit, model.voiced, 1); |
691 | 599 | ||
692 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 600 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
693 | WoE_index = encode_WoE(&model, e, c2->xq_enc); | 601 | WoE_index = encode_WoE(&model, e, c2->xq_enc); |
694 | pack(bits, &nbit, WoE_index, WO_E_BITS); | 602 | pack(bits, &nbit, WoE_index, WO_E_BITS); |
695 | 603 | ||
696 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); | 604 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); |
697 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 605 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { |
698 | pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); | 606 | pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); |
699 | } | 607 | } |
700 | pack(bits, &nbit, spare, 2); | 608 | pack(bits, &nbit, spare, 2); |
701 | 609 | ||
702 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 610 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); |
703 | } | 611 | } |
704 | 612 | ||
705 | |||
706 | /*---------------------------------------------------------------------------*\ | 613 | /*---------------------------------------------------------------------------*\ |
707 | 614 | ||
708 | FUNCTION....: codec2_decode_2400 | 615 | FUNCTION....: codec2_decode_2400 |
@@ -713,86 +620,84 @@ void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
713 | 620 | ||
714 | \*---------------------------------------------------------------------------*/ | 621 | \*---------------------------------------------------------------------------*/ |
715 | 622 | ||
716 | void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 623 | void codec2_decode_2400(struct CODEC2 *c2, short speech[], |
717 | { | 624 | const unsigned char *bits) { |
718 | MODEL model[2]; | 625 | MODEL model[2]; |
719 | int lsp_indexes[LPC_ORD]; | 626 | int lsp_indexes[LPC_ORD]; |
720 | float lsps[2][LPC_ORD]; | 627 | float lsps[2][LPC_ORD]; |
721 | int WoE_index; | 628 | int WoE_index; |
722 | float e[2]; | 629 | float e[2]; |
723 | float snr; | 630 | float snr; |
724 | float ak[2][LPC_ORD+1]; | 631 | float ak[2][LPC_ORD + 1]; |
725 | int i,j; | 632 | int i, j; |
726 | unsigned int nbit = 0; | 633 | unsigned int nbit = 0; |
727 | COMP Aw[FFT_ENC]; | 634 | COMP Aw[FFT_ENC]; |
728 | 635 | ||
729 | assert(c2 != NULL); | 636 | assert(c2 != NULL); |
730 | 637 | ||
731 | /* only need to zero these out due to (unused) snr calculation */ | 638 | /* only need to zero these out due to (unused) snr calculation */ |
732 | 639 | ||
733 | for(i=0; i<2; i++) | 640 | for (i = 0; i < 2; i++) |
734 | for(j=1; j<=MAX_AMP; j++) | 641 | for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; |
735 | model[i].A[j] = 0.0; | ||
736 | 642 | ||
737 | /* unpack bits from channel ------------------------------------*/ | 643 | /* unpack bits from channel ------------------------------------*/ |
738 | 644 | ||
739 | /* this will partially fill the model params for the 2 x 10ms | 645 | /* this will partially fill the model params for the 2 x 10ms |
740 | frames */ | 646 | frames */ |
741 | 647 | ||
742 | model[0].voiced = unpack(bits, &nbit, 1); | 648 | model[0].voiced = unpack(bits, &nbit, 1); |
743 | 649 | ||
744 | model[1].voiced = unpack(bits, &nbit, 1); | 650 | model[1].voiced = unpack(bits, &nbit, 1); |
745 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 651 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
746 | decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); | 652 | decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); |
747 | 653 | ||
748 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 654 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { |
749 | lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); | 655 | lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); |
750 | } | 656 | } |
751 | decode_lsps_scalar(&lsps[1][0], lsp_indexes, LPC_ORD); | 657 | decode_lsps_scalar(&lsps[1][0], lsp_indexes, LPC_ORD); |
752 | check_lsp_order(&lsps[1][0], LPC_ORD); | 658 | check_lsp_order(&lsps[1][0], LPC_ORD); |
753 | bw_expand_lsps(&lsps[1][0], LPC_ORD, 50.0, 100.0); | 659 | bw_expand_lsps(&lsps[1][0], LPC_ORD, 50.0, 100.0); |
754 | 660 | ||
755 | /* interpolate ------------------------------------------------*/ | 661 | /* interpolate ------------------------------------------------*/ |
756 | 662 | ||
757 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | 663 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 |
758 | 10ms frame between 20ms samples */ | 664 | 10ms frame between 20ms samples */ |
759 | 665 | ||
760 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | 666 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); |
761 | e[0] = interp_energy(c2->prev_e_dec, e[1]); | 667 | e[0] = interp_energy(c2->prev_e_dec, e[1]); |
762 | 668 | ||
763 | /* LSPs are sampled every 20ms so we interpolate the frame in | 669 | /* LSPs are sampled every 20ms so we interpolate the frame in |
764 | between, then recover spectral amplitudes */ | 670 | between, then recover spectral amplitudes */ |
765 | 671 | ||
766 | interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, LPC_ORD); | 672 | interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, |
767 | for(i=0; i<2; i++) { | 673 | LPC_ORD); |
768 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | 674 | for (i = 0; i < 2; i++) { |
769 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | 675 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); |
770 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | 676 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, |
771 | apply_lpc_correction(&model[i]); | 677 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); |
772 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | 678 | apply_lpc_correction(&model[i]); |
773 | 679 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], Aw, 1.0); | |
774 | /* dump parameters for deep learning experiments */ | 680 | |
775 | 681 | /* dump parameters for deep learning experiments */ | |
776 | if (c2->fmlfeat != NULL) { | 682 | |
777 | /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ | 683 | if (c2->fmlfeat != NULL) { |
778 | fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); | 684 | /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ |
779 | fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); | 685 | fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); |
780 | fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); | 686 | fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); |
781 | float voiced_float = model[i].voiced; | 687 | fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); |
782 | fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); | 688 | float voiced_float = model[i].voiced; |
783 | fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); | 689 | fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); |
784 | } | 690 | fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); |
785 | } | 691 | } |
692 | } | ||
786 | 693 | ||
787 | /* update memories for next frame ----------------------------*/ | 694 | /* update memories for next frame ----------------------------*/ |
788 | 695 | ||
789 | c2->prev_model_dec = model[1]; | 696 | c2->prev_model_dec = model[1]; |
790 | c2->prev_e_dec = e[1]; | 697 | c2->prev_e_dec = e[1]; |
791 | for(i=0; i<LPC_ORD; i++) | 698 | for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[1][i]; |
792 | c2->prev_lsps_dec[i] = lsps[1][i]; | ||
793 | } | 699 | } |
794 | 700 | ||
795 | |||
796 | /*---------------------------------------------------------------------------*\ | 701 | /*---------------------------------------------------------------------------*\ |
797 | 702 | ||
798 | FUNCTION....: codec2_encode_1600 | 703 | FUNCTION....: codec2_encode_1600 |
@@ -821,65 +726,64 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * | |||
821 | 726 | ||
822 | \*---------------------------------------------------------------------------*/ | 727 | \*---------------------------------------------------------------------------*/ |
823 | 728 | ||
824 | void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 729 | void codec2_encode_1600(struct CODEC2 *c2, unsigned char *bits, |
825 | { | 730 | short speech[]) { |
826 | MODEL model; | 731 | MODEL model; |
827 | float lsps[LPC_ORD]; | 732 | float lsps[LPC_ORD]; |
828 | float ak[LPC_ORD+1]; | 733 | float ak[LPC_ORD + 1]; |
829 | float e; | 734 | float e; |
830 | int lsp_indexes[LPC_ORD]; | 735 | int lsp_indexes[LPC_ORD]; |
831 | int Wo_index, e_index; | 736 | int Wo_index, e_index; |
832 | int i; | 737 | int i; |
833 | unsigned int nbit = 0; | 738 | unsigned int nbit = 0; |
834 | 739 | ||
835 | assert(c2 != NULL); | 740 | assert(c2 != NULL); |
836 | 741 | ||
837 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 742 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
838 | 743 | ||
839 | /* frame 1: - voicing ---------------------------------------------*/ | 744 | /* frame 1: - voicing ---------------------------------------------*/ |
840 | 745 | ||
841 | analyse_one_frame(c2, &model, speech); | 746 | analyse_one_frame(c2, &model, speech); |
842 | pack(bits, &nbit, model.voiced, 1); | 747 | pack(bits, &nbit, model.voiced, 1); |
843 | 748 | ||
844 | /* frame 2: - voicing, scalar Wo & E -------------------------------*/ | 749 | /* frame 2: - voicing, scalar Wo & E -------------------------------*/ |
845 | 750 | ||
846 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); | 751 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); |
847 | pack(bits, &nbit, model.voiced, 1); | 752 | pack(bits, &nbit, model.voiced, 1); |
848 | 753 | ||
849 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); | 754 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); |
850 | pack(bits, &nbit, Wo_index, WO_BITS); | 755 | pack(bits, &nbit, Wo_index, WO_BITS); |
851 | 756 | ||
852 | /* need to run this just to get LPC energy */ | 757 | /* need to run this just to get LPC energy */ |
853 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 758 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
854 | e_index = encode_energy(e, E_BITS); | 759 | e_index = encode_energy(e, E_BITS); |
855 | pack(bits, &nbit, e_index, E_BITS); | 760 | pack(bits, &nbit, e_index, E_BITS); |
856 | 761 | ||
857 | /* frame 3: - voicing ---------------------------------------------*/ | 762 | /* frame 3: - voicing ---------------------------------------------*/ |
858 | 763 | ||
859 | analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); | 764 | analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); |
860 | pack(bits, &nbit, model.voiced, 1); | 765 | pack(bits, &nbit, model.voiced, 1); |
861 | 766 | ||
862 | /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ | 767 | /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ |
863 | 768 | ||
864 | analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); | 769 | analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); |
865 | pack(bits, &nbit, model.voiced, 1); | 770 | pack(bits, &nbit, model.voiced, 1); |
866 | 771 | ||
867 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); | 772 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); |
868 | pack(bits, &nbit, Wo_index, WO_BITS); | 773 | pack(bits, &nbit, Wo_index, WO_BITS); |
869 | 774 | ||
870 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 775 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
871 | e_index = encode_energy(e, E_BITS); | 776 | e_index = encode_energy(e, E_BITS); |
872 | pack(bits, &nbit, e_index, E_BITS); | 777 | pack(bits, &nbit, e_index, E_BITS); |
873 | 778 | ||
874 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); | 779 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); |
875 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 780 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { |
876 | pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); | 781 | pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); |
877 | } | 782 | } |
878 | 783 | ||
879 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 784 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); |
880 | } | 785 | } |
881 | 786 | ||
882 | |||
883 | /*---------------------------------------------------------------------------*\ | 787 | /*---------------------------------------------------------------------------*\ |
884 | 788 | ||
885 | FUNCTION....: codec2_decode_1600 | 789 | FUNCTION....: codec2_decode_1600 |
@@ -890,91 +794,89 @@ void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
890 | 794 | ||
891 | \*---------------------------------------------------------------------------*/ | 795 | \*---------------------------------------------------------------------------*/ |
892 | 796 | ||
893 | void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 797 | void codec2_decode_1600(struct CODEC2 *c2, short speech[], |
894 | { | 798 | const unsigned char *bits) { |
895 | MODEL model[4]; | 799 | MODEL model[4]; |
896 | int lsp_indexes[LPC_ORD]; | 800 | int lsp_indexes[LPC_ORD]; |
897 | float lsps[4][LPC_ORD]; | 801 | float lsps[4][LPC_ORD]; |
898 | int Wo_index, e_index; | 802 | int Wo_index, e_index; |
899 | float e[4]; | 803 | float e[4]; |
900 | float snr; | 804 | float snr; |
901 | float ak[4][LPC_ORD+1]; | 805 | float ak[4][LPC_ORD + 1]; |
902 | int i,j; | 806 | int i, j; |
903 | unsigned int nbit = 0; | 807 | unsigned int nbit = 0; |
904 | float weight; | 808 | float weight; |
905 | COMP Aw[FFT_ENC]; | 809 | COMP Aw[FFT_ENC]; |
906 | 810 | ||
907 | assert(c2 != NULL); | 811 | assert(c2 != NULL); |
908 | 812 | ||
909 | /* only need to zero these out due to (unused) snr calculation */ | 813 | /* only need to zero these out due to (unused) snr calculation */ |
910 | 814 | ||
911 | for(i=0; i<4; i++) | 815 | for (i = 0; i < 4; i++) |
912 | for(j=1; j<=MAX_AMP; j++) | 816 | for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; |
913 | model[i].A[j] = 0.0; | 817 | |
914 | 818 | /* unpack bits from channel ------------------------------------*/ | |
915 | /* unpack bits from channel ------------------------------------*/ | 819 | |
916 | 820 | /* this will partially fill the model params for the 4 x 10ms | |
917 | /* this will partially fill the model params for the 4 x 10ms | 821 | frames */ |
918 | frames */ | 822 | |
919 | 823 | model[0].voiced = unpack(bits, &nbit, 1); | |
920 | model[0].voiced = unpack(bits, &nbit, 1); | 824 | |
921 | 825 | model[1].voiced = unpack(bits, &nbit, 1); | |
922 | model[1].voiced = unpack(bits, &nbit, 1); | 826 | Wo_index = unpack(bits, &nbit, WO_BITS); |
923 | Wo_index = unpack(bits, &nbit, WO_BITS); | 827 | model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); |
924 | model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); | 828 | model[1].L = PI / model[1].Wo; |
925 | model[1].L = PI/model[1].Wo; | 829 | |
926 | 830 | e_index = unpack(bits, &nbit, E_BITS); | |
927 | e_index = unpack(bits, &nbit, E_BITS); | 831 | e[1] = decode_energy(e_index, E_BITS); |
928 | e[1] = decode_energy(e_index, E_BITS); | 832 | |
929 | 833 | model[2].voiced = unpack(bits, &nbit, 1); | |
930 | model[2].voiced = unpack(bits, &nbit, 1); | 834 | |
931 | 835 | model[3].voiced = unpack(bits, &nbit, 1); | |
932 | model[3].voiced = unpack(bits, &nbit, 1); | 836 | Wo_index = unpack(bits, &nbit, WO_BITS); |
933 | Wo_index = unpack(bits, &nbit, WO_BITS); | 837 | model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); |
934 | model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); | 838 | model[3].L = PI / model[3].Wo; |
935 | model[3].L = PI/model[3].Wo; | 839 | |
936 | 840 | e_index = unpack(bits, &nbit, E_BITS); | |
937 | e_index = unpack(bits, &nbit, E_BITS); | 841 | e[3] = decode_energy(e_index, E_BITS); |
938 | e[3] = decode_energy(e_index, E_BITS); | 842 | |
939 | 843 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { | |
940 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 844 | lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); |
941 | lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); | 845 | } |
942 | } | 846 | decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); |
943 | decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); | 847 | check_lsp_order(&lsps[3][0], LPC_ORD); |
944 | check_lsp_order(&lsps[3][0], LPC_ORD); | 848 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); |
945 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); | 849 | |
946 | 850 | /* interpolate ------------------------------------------------*/ | |
947 | /* interpolate ------------------------------------------------*/ | 851 | |
948 | 852 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | |
949 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | 853 | 10ms frame between 20ms samples */ |
950 | 10ms frame between 20ms samples */ | 854 | |
951 | 855 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | |
952 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | 856 | e[0] = interp_energy(c2->prev_e_dec, e[1]); |
953 | e[0] = interp_energy(c2->prev_e_dec, e[1]); | 857 | interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); |
954 | interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); | 858 | e[2] = interp_energy(e[1], e[3]); |
955 | e[2] = interp_energy(e[1], e[3]); | 859 | |
956 | 860 | /* LSPs are sampled every 40ms so we interpolate the 3 frames in | |
957 | /* LSPs are sampled every 40ms so we interpolate the 3 frames in | 861 | between, then recover spectral amplitudes */ |
958 | between, then recover spectral amplitudes */ | 862 | |
959 | 863 | for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { | |
960 | for(i=0, weight=0.25; i<3; i++, weight += 0.25) { | 864 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, |
961 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); | 865 | LPC_ORD); |
962 | } | 866 | } |
963 | for(i=0; i<4; i++) { | 867 | for (i = 0; i < 4; i++) { |
964 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | 868 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); |
965 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | 869 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, |
966 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | 870 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); |
967 | apply_lpc_correction(&model[i]); | 871 | apply_lpc_correction(&model[i]); |
968 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | 872 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], Aw, 1.0); |
969 | } | 873 | } |
970 | 874 | ||
971 | /* update memories for next frame ----------------------------*/ | 875 | /* update memories for next frame ----------------------------*/ |
972 | 876 | ||
973 | c2->prev_model_dec = model[3]; | 877 | c2->prev_model_dec = model[3]; |
974 | c2->prev_e_dec = e[3]; | 878 | c2->prev_e_dec = e[3]; |
975 | for(i=0; i<LPC_ORD; i++) | 879 | for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; |
976 | c2->prev_lsps_dec[i] = lsps[3][i]; | ||
977 | |||
978 | } | 880 | } |
979 | 881 | ||
980 | /*---------------------------------------------------------------------------*\ | 882 | /*---------------------------------------------------------------------------*\ |
@@ -1004,60 +906,59 @@ void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * | |||
1004 | 906 | ||
1005 | \*---------------------------------------------------------------------------*/ | 907 | \*---------------------------------------------------------------------------*/ |
1006 | 908 | ||
1007 | void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 909 | void codec2_encode_1400(struct CODEC2 *c2, unsigned char *bits, |
1008 | { | 910 | short speech[]) { |
1009 | MODEL model; | 911 | MODEL model; |
1010 | float lsps[LPC_ORD]; | 912 | float lsps[LPC_ORD]; |
1011 | float ak[LPC_ORD+1]; | 913 | float ak[LPC_ORD + 1]; |
1012 | float e; | 914 | float e; |
1013 | int lsp_indexes[LPC_ORD]; | 915 | int lsp_indexes[LPC_ORD]; |
1014 | int WoE_index; | 916 | int WoE_index; |
1015 | int i; | 917 | int i; |
1016 | unsigned int nbit = 0; | 918 | unsigned int nbit = 0; |
1017 | 919 | ||
1018 | assert(c2 != NULL); | 920 | assert(c2 != NULL); |
1019 | 921 | ||
1020 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 922 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
1021 | 923 | ||
1022 | /* frame 1: - voicing ---------------------------------------------*/ | 924 | /* frame 1: - voicing ---------------------------------------------*/ |
1023 | 925 | ||
1024 | analyse_one_frame(c2, &model, speech); | 926 | analyse_one_frame(c2, &model, speech); |
1025 | pack(bits, &nbit, model.voiced, 1); | 927 | pack(bits, &nbit, model.voiced, 1); |
1026 | 928 | ||
1027 | /* frame 2: - voicing, joint Wo & E -------------------------------*/ | 929 | /* frame 2: - voicing, joint Wo & E -------------------------------*/ |
1028 | 930 | ||
1029 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); | 931 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); |
1030 | pack(bits, &nbit, model.voiced, 1); | 932 | pack(bits, &nbit, model.voiced, 1); |
1031 | 933 | ||
1032 | /* need to run this just to get LPC energy */ | 934 | /* need to run this just to get LPC energy */ |
1033 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 935 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
1034 | 936 | ||
1035 | WoE_index = encode_WoE(&model, e, c2->xq_enc); | 937 | WoE_index = encode_WoE(&model, e, c2->xq_enc); |
1036 | pack(bits, &nbit, WoE_index, WO_E_BITS); | 938 | pack(bits, &nbit, WoE_index, WO_E_BITS); |
1037 | 939 | ||
1038 | /* frame 3: - voicing ---------------------------------------------*/ | 940 | /* frame 3: - voicing ---------------------------------------------*/ |
1039 | 941 | ||
1040 | analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); | 942 | analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); |
1041 | pack(bits, &nbit, model.voiced, 1); | 943 | pack(bits, &nbit, model.voiced, 1); |
1042 | 944 | ||
1043 | /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ | 945 | /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ |
1044 | 946 | ||
1045 | analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); | 947 | analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); |
1046 | pack(bits, &nbit, model.voiced, 1); | 948 | pack(bits, &nbit, model.voiced, 1); |
1047 | 949 | ||
1048 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 950 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
1049 | WoE_index = encode_WoE(&model, e, c2->xq_enc); | 951 | WoE_index = encode_WoE(&model, e, c2->xq_enc); |
1050 | pack(bits, &nbit, WoE_index, WO_E_BITS); | 952 | pack(bits, &nbit, WoE_index, WO_E_BITS); |
1051 | 953 | ||
1052 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); | 954 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); |
1053 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 955 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { |
1054 | pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); | 956 | pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); |
1055 | } | 957 | } |
1056 | 958 | ||
1057 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 959 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); |
1058 | } | 960 | } |
1059 | 961 | ||
1060 | |||
1061 | /*---------------------------------------------------------------------------*\ | 962 | /*---------------------------------------------------------------------------*\ |
1062 | 963 | ||
1063 | FUNCTION....: codec2_decode_1400 | 964 | FUNCTION....: codec2_decode_1400 |
@@ -1068,83 +969,81 @@ void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
1068 | 969 | ||
1069 | \*---------------------------------------------------------------------------*/ | 970 | \*---------------------------------------------------------------------------*/ |
1070 | 971 | ||
1071 | void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 972 | void codec2_decode_1400(struct CODEC2 *c2, short speech[], |
1072 | { | 973 | const unsigned char *bits) { |
1073 | MODEL model[4]; | 974 | MODEL model[4]; |
1074 | int lsp_indexes[LPC_ORD]; | 975 | int lsp_indexes[LPC_ORD]; |
1075 | float lsps[4][LPC_ORD]; | 976 | float lsps[4][LPC_ORD]; |
1076 | int WoE_index; | 977 | int WoE_index; |
1077 | float e[4]; | 978 | float e[4]; |
1078 | float snr; | 979 | float snr; |
1079 | float ak[4][LPC_ORD+1]; | 980 | float ak[4][LPC_ORD + 1]; |
1080 | int i,j; | 981 | int i, j; |
1081 | unsigned int nbit = 0; | 982 | unsigned int nbit = 0; |
1082 | float weight; | 983 | float weight; |
1083 | COMP Aw[FFT_ENC]; | 984 | COMP Aw[FFT_ENC]; |
1084 | 985 | ||
1085 | assert(c2 != NULL); | 986 | assert(c2 != NULL); |
1086 | 987 | ||
1087 | /* only need to zero these out due to (unused) snr calculation */ | 988 | /* only need to zero these out due to (unused) snr calculation */ |
1088 | 989 | ||
1089 | for(i=0; i<4; i++) | 990 | for (i = 0; i < 4; i++) |
1090 | for(j=1; j<=MAX_AMP; j++) | 991 | for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; |
1091 | model[i].A[j] = 0.0; | 992 | |
1092 | 993 | /* unpack bits from channel ------------------------------------*/ | |
1093 | /* unpack bits from channel ------------------------------------*/ | 994 | |
1094 | 995 | /* this will partially fill the model params for the 4 x 10ms | |
1095 | /* this will partially fill the model params for the 4 x 10ms | 996 | frames */ |
1096 | frames */ | 997 | |
1097 | 998 | model[0].voiced = unpack(bits, &nbit, 1); | |
1098 | model[0].voiced = unpack(bits, &nbit, 1); | 999 | |
1099 | 1000 | model[1].voiced = unpack(bits, &nbit, 1); | |
1100 | model[1].voiced = unpack(bits, &nbit, 1); | 1001 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
1101 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 1002 | decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); |
1102 | decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); | 1003 | |
1103 | 1004 | model[2].voiced = unpack(bits, &nbit, 1); | |
1104 | model[2].voiced = unpack(bits, &nbit, 1); | 1005 | |
1105 | 1006 | model[3].voiced = unpack(bits, &nbit, 1); | |
1106 | model[3].voiced = unpack(bits, &nbit, 1); | 1007 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
1107 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 1008 | decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); |
1108 | decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); | 1009 | |
1109 | 1010 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { | |
1110 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 1011 | lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); |
1111 | lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); | 1012 | } |
1112 | } | 1013 | decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); |
1113 | decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); | 1014 | check_lsp_order(&lsps[3][0], LPC_ORD); |
1114 | check_lsp_order(&lsps[3][0], LPC_ORD); | 1015 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); |
1115 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); | 1016 | |
1116 | 1017 | /* interpolate ------------------------------------------------*/ | |
1117 | /* interpolate ------------------------------------------------*/ | 1018 | |
1118 | 1019 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | |
1119 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | 1020 | 10ms frame between 20ms samples */ |
1120 | 10ms frame between 20ms samples */ | 1021 | |
1121 | 1022 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | |
1122 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | 1023 | e[0] = interp_energy(c2->prev_e_dec, e[1]); |
1123 | e[0] = interp_energy(c2->prev_e_dec, e[1]); | 1024 | interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); |
1124 | interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); | 1025 | e[2] = interp_energy(e[1], e[3]); |
1125 | e[2] = interp_energy(e[1], e[3]); | 1026 | |
1126 | 1027 | /* LSPs are sampled every 40ms so we interpolate the 3 frames in | |
1127 | /* LSPs are sampled every 40ms so we interpolate the 3 frames in | 1028 | between, then recover spectral amplitudes */ |
1128 | between, then recover spectral amplitudes */ | 1029 | |
1129 | 1030 | for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { | |
1130 | for(i=0, weight=0.25; i<3; i++, weight += 0.25) { | 1031 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, |
1131 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); | 1032 | LPC_ORD); |
1132 | } | 1033 | } |
1133 | for(i=0; i<4; i++) { | 1034 | for (i = 0; i < 4; i++) { |
1134 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | 1035 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); |
1135 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | 1036 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, |
1136 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | 1037 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); |
1137 | apply_lpc_correction(&model[i]); | 1038 | apply_lpc_correction(&model[i]); |
1138 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | 1039 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], Aw, 1.0); |
1139 | } | 1040 | } |
1140 | 1041 | ||
1141 | /* update memories for next frame ----------------------------*/ | 1042 | /* update memories for next frame ----------------------------*/ |
1142 | 1043 | ||
1143 | c2->prev_model_dec = model[3]; | 1044 | c2->prev_model_dec = model[3]; |
1144 | c2->prev_e_dec = e[3]; | 1045 | c2->prev_e_dec = e[3]; |
1145 | for(i=0; i<LPC_ORD; i++) | 1046 | for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; |
1146 | c2->prev_lsps_dec[i] = lsps[3][i]; | ||
1147 | |||
1148 | } | 1047 | } |
1149 | 1048 | ||
1150 | /*---------------------------------------------------------------------------*\ | 1049 | /*---------------------------------------------------------------------------*\ |
@@ -1175,66 +1074,56 @@ void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * | |||
1175 | 1074 | ||
1176 | \*---------------------------------------------------------------------------*/ | 1075 | \*---------------------------------------------------------------------------*/ |
1177 | 1076 | ||
1178 | void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 1077 | void codec2_encode_1300(struct CODEC2 *c2, unsigned char *bits, |
1179 | { | 1078 | short speech[]) { |
1180 | MODEL model; | 1079 | MODEL model; |
1181 | float lsps[LPC_ORD]; | 1080 | float lsps[LPC_ORD]; |
1182 | float ak[LPC_ORD+1]; | 1081 | float ak[LPC_ORD + 1]; |
1183 | float e; | 1082 | float e; |
1184 | int lsp_indexes[LPC_ORD]; | 1083 | int lsp_indexes[LPC_ORD]; |
1185 | int Wo_index, e_index; | 1084 | int Wo_index, e_index; |
1186 | int i; | 1085 | int i; |
1187 | unsigned int nbit = 0; | 1086 | unsigned int nbit = 0; |
1188 | //#ifdef PROFILE | ||
1189 | //unsigned int quant_start; | ||
1190 | //#endif | ||
1191 | 1087 | ||
1192 | assert(c2 != NULL); | 1088 | assert(c2 != NULL); |
1193 | 1089 | ||
1194 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 1090 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
1195 | 1091 | ||
1196 | /* frame 1: - voicing ---------------------------------------------*/ | 1092 | /* frame 1: - voicing ---------------------------------------------*/ |
1197 | 1093 | ||
1198 | analyse_one_frame(c2, &model, speech); | 1094 | analyse_one_frame(c2, &model, speech); |
1199 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); | 1095 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); |
1200 | 1096 | ||
1201 | /* frame 2: - voicing ---------------------------------------------*/ | 1097 | /* frame 2: - voicing ---------------------------------------------*/ |
1202 | 1098 | ||
1203 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); | 1099 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); |
1204 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); | 1100 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); |
1205 | 1101 | ||
1206 | /* frame 3: - voicing ---------------------------------------------*/ | 1102 | /* frame 3: - voicing ---------------------------------------------*/ |
1207 | 1103 | ||
1208 | analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); | 1104 | analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); |
1209 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); | 1105 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); |
1210 | 1106 | ||
1211 | /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ | 1107 | /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ |
1212 | 1108 | ||
1213 | analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); | 1109 | analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); |
1214 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); | 1110 | pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); |
1215 | 1111 | ||
1216 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); | 1112 | Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS); |
1217 | pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray); | 1113 | pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray); |
1218 | 1114 | ||
1219 | //#ifdef PROFILE | 1115 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
1220 | //quant_start = machdep_profile_sample(); | 1116 | e_index = encode_energy(e, E_BITS); |
1221 | //#endif | 1117 | pack_natural_or_gray(bits, &nbit, e_index, E_BITS, c2->gray); |
1222 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | ||
1223 | e_index = encode_energy(e, E_BITS); | ||
1224 | pack_natural_or_gray(bits, &nbit, e_index, E_BITS, c2->gray); | ||
1225 | 1118 | ||
1226 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); | 1119 | encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); |
1227 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 1120 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { |
1228 | pack_natural_or_gray(bits, &nbit, lsp_indexes[i], lsp_bits(i), c2->gray); | 1121 | pack_natural_or_gray(bits, &nbit, lsp_indexes[i], lsp_bits(i), c2->gray); |
1229 | } | 1122 | } |
1230 | //#ifdef PROFILE | ||
1231 | //machdep_profile_sample_and_log(quant_start, " quant/packing"); | ||
1232 | //#endif | ||
1233 | 1123 | ||
1234 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 1124 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); |
1235 | } | 1125 | } |
1236 | 1126 | ||
1237 | |||
1238 | /*---------------------------------------------------------------------------*\ | 1127 | /*---------------------------------------------------------------------------*\ |
1239 | 1128 | ||
1240 | FUNCTION....: codec2_decode_1300 | 1129 | FUNCTION....: codec2_decode_1300 |
@@ -1244,118 +1133,106 @@ void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
1244 | Decodes frames of 52 bits into 320 samples (40ms) of speech. | 1133 | Decodes frames of 52 bits into 320 samples (40ms) of speech. |
1245 | 1134 | ||
1246 | \*---------------------------------------------------------------------------*/ | 1135 | \*---------------------------------------------------------------------------*/ |
1247 | static int frames; | ||
1248 | void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est) | ||
1249 | { | ||
1250 | MODEL model[4]; | ||
1251 | int lsp_indexes[LPC_ORD]; | ||
1252 | float lsps[4][LPC_ORD]; | ||
1253 | int Wo_index, e_index; | ||
1254 | float e[4]; | ||
1255 | float snr; | ||
1256 | float ak[4][LPC_ORD+1]; | ||
1257 | int i,j; | ||
1258 | unsigned int nbit = 0; | ||
1259 | float weight; | ||
1260 | COMP Aw[FFT_ENC]; | ||
1261 | //PROFILE_VAR(recover_start); | ||
1262 | |||
1263 | assert(c2 != NULL); | ||
1264 | frames+= 4; | ||
1265 | /* only need to zero these out due to (unused) snr calculation */ | ||
1266 | |||
1267 | for(i=0; i<4; i++) | ||
1268 | for(j=1; j<=MAX_AMP; j++) | ||
1269 | model[i].A[j] = 0.0; | ||
1270 | |||
1271 | /* unpack bits from channel ------------------------------------*/ | ||
1272 | |||
1273 | /* this will partially fill the model params for the 4 x 10ms | ||
1274 | frames */ | ||
1275 | |||
1276 | model[0].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1277 | model[1].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1278 | model[2].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1279 | model[3].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1280 | |||
1281 | Wo_index = unpack_natural_or_gray(bits, &nbit, WO_BITS, c2->gray); | ||
1282 | model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); | ||
1283 | model[3].L = PI/model[3].Wo; | ||
1284 | 1136 | ||
1285 | e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); | 1137 | void codec2_decode_1300(struct CODEC2 *c2, short speech[], |
1286 | e[3] = decode_energy(e_index, E_BITS); | 1138 | const unsigned char *bits, float ber_est) { |
1287 | //fprintf(stderr, "%d %f\n", e_index, e[3]); | 1139 | MODEL model[4]; |
1140 | int lsp_indexes[LPC_ORD]; | ||
1141 | float lsps[4][LPC_ORD]; | ||
1142 | int Wo_index, e_index; | ||
1143 | float e[4]; | ||
1144 | float snr; | ||
1145 | float ak[4][LPC_ORD + 1]; | ||
1146 | int i, j; | ||
1147 | unsigned int nbit = 0; | ||
1148 | float weight; | ||
1149 | COMP Aw[FFT_ENC]; | ||
1150 | |||
1151 | assert(c2 != NULL); | ||
1152 | |||
1153 | /* only need to zero these out due to (unused) snr calculation */ | ||
1154 | |||
1155 | for (i = 0; i < 4; i++) | ||
1156 | for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; | ||
1157 | |||
1158 | /* unpack bits from channel ------------------------------------*/ | ||
1159 | |||
1160 | /* this will partially fill the model params for the 4 x 10ms | ||
1161 | frames */ | ||
1162 | |||
1163 | model[0].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1164 | model[1].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1165 | model[2].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1166 | model[3].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray); | ||
1167 | |||
1168 | Wo_index = unpack_natural_or_gray(bits, &nbit, WO_BITS, c2->gray); | ||
1169 | model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS); | ||
1170 | model[3].L = PI / model[3].Wo; | ||
1171 | |||
1172 | e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); | ||
1173 | e[3] = decode_energy(e_index, E_BITS); | ||
1174 | |||
1175 | for (i = 0; i < LSP_SCALAR_INDEXES; i++) { | ||
1176 | lsp_indexes[i] = unpack_natural_or_gray(bits, &nbit, lsp_bits(i), c2->gray); | ||
1177 | } | ||
1178 | decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); | ||
1179 | check_lsp_order(&lsps[3][0], LPC_ORD); | ||
1180 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); | ||
1181 | |||
1182 | if (ber_est > 0.15) { | ||
1183 | model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced = 0; | ||
1184 | e[3] = decode_energy(10, E_BITS); | ||
1185 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0); | ||
1186 | // fprintf(stderr, "soft mute\n"); | ||
1187 | } | ||
1188 | |||
1189 | /* interpolate ------------------------------------------------*/ | ||
1190 | |||
1191 | /* Wo, energy, and LSPs are sampled every 40ms so we interpolate | ||
1192 | the 3 frames in between */ | ||
1193 | |||
1194 | for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { | ||
1195 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, | ||
1196 | LPC_ORD); | ||
1197 | interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, | ||
1198 | c2->c2const.Wo_min); | ||
1199 | e[i] = interp_energy2(c2->prev_e_dec, e[3], weight); | ||
1200 | } | ||
1201 | |||
1202 | /* then recover spectral amplitudes */ | ||
1203 | |||
1204 | for (i = 0; i < 4; i++) { | ||
1205 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | ||
1206 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | ||
1207 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | ||
1208 | apply_lpc_correction(&model[i]); | ||
1209 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], Aw, 1.0); | ||
1210 | |||
1211 | /* dump parameters for deep learning experiments */ | ||
1288 | 1212 | ||
1289 | for(i=0; i<LSP_SCALAR_INDEXES; i++) { | 1213 | if (c2->fmlfeat != NULL) { |
1290 | lsp_indexes[i] = unpack_natural_or_gray(bits, &nbit, lsp_bits(i), c2->gray); | 1214 | /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ |
1291 | } | 1215 | fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); |
1292 | decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); | 1216 | fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); |
1293 | check_lsp_order(&lsps[3][0], LPC_ORD); | 1217 | fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); |
1294 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); | 1218 | float voiced_float = model[i].voiced; |
1295 | 1219 | fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); | |
1296 | if (ber_est > 0.15) { | 1220 | fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); |
1297 | model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced = 0; | 1221 | } |
1298 | e[3] = decode_energy(10, E_BITS); | 1222 | } |
1299 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0); | 1223 | |
1300 | //fprintf(stderr, "soft mute\n"); | 1224 | #ifdef DUMP |
1301 | } | 1225 | dump_lsp_(&lsps[3][0]); |
1302 | 1226 | dump_ak_(&ak[3][0], LPC_ORD); | |
1303 | /* interpolate ------------------------------------------------*/ | 1227 | #endif |
1304 | |||
1305 | /* Wo, energy, and LSPs are sampled every 40ms so we interpolate | ||
1306 | the 3 frames in between */ | ||
1307 | |||
1308 | //PROFILE_SAMPLE(recover_start); | ||
1309 | for(i=0, weight=0.25; i<3; i++, weight += 0.25) { | ||
1310 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); | ||
1311 | interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min); | ||
1312 | e[i] = interp_energy2(c2->prev_e_dec, e[3],weight); | ||
1313 | } | ||
1314 | 1228 | ||
1315 | /* then recover spectral amplitudes */ | 1229 | /* update memories for next frame ----------------------------*/ |
1316 | |||
1317 | for(i=0; i<4; i++) { | ||
1318 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | ||
1319 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | ||
1320 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | ||
1321 | apply_lpc_correction(&model[i]); | ||
1322 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | ||
1323 | |||
1324 | /* dump parameters for deep learning experiments */ | ||
1325 | |||
1326 | if (c2->fmlfeat != NULL) { | ||
1327 | /* 10 LSPs - energy - Wo - voicing flag - 10 LPCs */ | ||
1328 | fwrite(&lsps[i][0], LPC_ORD, sizeof(float), c2->fmlfeat); | ||
1329 | fwrite(&e[i], 1, sizeof(float), c2->fmlfeat); | ||
1330 | fwrite(&model[i].Wo, 1, sizeof(float), c2->fmlfeat); | ||
1331 | float voiced_float = model[i].voiced; | ||
1332 | fwrite(&voiced_float, 1, sizeof(float), c2->fmlfeat); | ||
1333 | fwrite(&ak[i][1], LPC_ORD, sizeof(float), c2->fmlfeat); | ||
1334 | } | ||
1335 | } | ||
1336 | /* | ||
1337 | for(i=0; i<4; i++) { | ||
1338 | printf("%d Wo: %f L: %d v: %d\n", frames, model[i].Wo, model[i].L, model[i].voiced); | ||
1339 | } | ||
1340 | if (frames == 4*50) | ||
1341 | exit(0); | ||
1342 | */ | ||
1343 | //PROFILE_SAMPLE_AND_LOG2(recover_start, " recover"); | ||
1344 | #ifdef DUMP | ||
1345 | dump_lsp_(&lsps[3][0]); | ||
1346 | dump_ak_(&ak[3][0], LPC_ORD); | ||
1347 | #endif | ||
1348 | |||
1349 | /* update memories for next frame ----------------------------*/ | ||
1350 | |||
1351 | c2->prev_model_dec = model[3]; | ||
1352 | c2->prev_e_dec = e[3]; | ||
1353 | for(i=0; i<LPC_ORD; i++) | ||
1354 | c2->prev_lsps_dec[i] = lsps[3][i]; | ||
1355 | 1230 | ||
1231 | c2->prev_model_dec = model[3]; | ||
1232 | c2->prev_e_dec = e[3]; | ||
1233 | for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; | ||
1356 | } | 1234 | } |
1357 | 1235 | ||
1358 | |||
1359 | /*---------------------------------------------------------------------------*\ | 1236 | /*---------------------------------------------------------------------------*\ |
1360 | 1237 | ||
1361 | FUNCTION....: codec2_encode_1200 | 1238 | FUNCTION....: codec2_encode_1200 |
@@ -1384,63 +1261,62 @@ void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * | |||
1384 | 1261 | ||
1385 | \*---------------------------------------------------------------------------*/ | 1262 | \*---------------------------------------------------------------------------*/ |
1386 | 1263 | ||
1387 | void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 1264 | void codec2_encode_1200(struct CODEC2 *c2, unsigned char *bits, |
1388 | { | 1265 | short speech[]) { |
1389 | MODEL model; | 1266 | MODEL model; |
1390 | float lsps[LPC_ORD]; | 1267 | float lsps[LPC_ORD]; |
1391 | float lsps_[LPC_ORD]; | 1268 | float lsps_[LPC_ORD]; |
1392 | float ak[LPC_ORD+1]; | 1269 | float ak[LPC_ORD + 1]; |
1393 | float e; | 1270 | float e; |
1394 | int lsp_indexes[LPC_ORD]; | 1271 | int lsp_indexes[LPC_ORD]; |
1395 | int WoE_index; | 1272 | int WoE_index; |
1396 | int i; | 1273 | int i; |
1397 | int spare = 0; | 1274 | int spare = 0; |
1398 | unsigned int nbit = 0; | 1275 | unsigned int nbit = 0; |
1399 | 1276 | ||
1400 | assert(c2 != NULL); | 1277 | assert(c2 != NULL); |
1401 | 1278 | ||
1402 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 1279 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
1403 | 1280 | ||
1404 | /* frame 1: - voicing ---------------------------------------------*/ | 1281 | /* frame 1: - voicing ---------------------------------------------*/ |
1405 | 1282 | ||
1406 | analyse_one_frame(c2, &model, speech); | 1283 | analyse_one_frame(c2, &model, speech); |
1407 | pack(bits, &nbit, model.voiced, 1); | 1284 | pack(bits, &nbit, model.voiced, 1); |
1408 | 1285 | ||
1409 | /* frame 2: - voicing, joint Wo & E -------------------------------*/ | 1286 | /* frame 2: - voicing, joint Wo & E -------------------------------*/ |
1410 | 1287 | ||
1411 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); | 1288 | analyse_one_frame(c2, &model, &speech[c2->n_samp]); |
1412 | pack(bits, &nbit, model.voiced, 1); | 1289 | pack(bits, &nbit, model.voiced, 1); |
1413 | 1290 | ||
1414 | /* need to run this just to get LPC energy */ | 1291 | /* need to run this just to get LPC energy */ |
1415 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 1292 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
1416 | 1293 | ||
1417 | WoE_index = encode_WoE(&model, e, c2->xq_enc); | 1294 | WoE_index = encode_WoE(&model, e, c2->xq_enc); |
1418 | pack(bits, &nbit, WoE_index, WO_E_BITS); | 1295 | pack(bits, &nbit, WoE_index, WO_E_BITS); |
1419 | 1296 | ||
1420 | /* frame 3: - voicing ---------------------------------------------*/ | 1297 | /* frame 3: - voicing ---------------------------------------------*/ |
1421 | 1298 | ||
1422 | analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); | 1299 | analyse_one_frame(c2, &model, &speech[2 * c2->n_samp]); |
1423 | pack(bits, &nbit, model.voiced, 1); | 1300 | pack(bits, &nbit, model.voiced, 1); |
1424 | 1301 | ||
1425 | /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ | 1302 | /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ |
1426 | 1303 | ||
1427 | analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); | 1304 | analyse_one_frame(c2, &model, &speech[3 * c2->n_samp]); |
1428 | pack(bits, &nbit, model.voiced, 1); | 1305 | pack(bits, &nbit, model.voiced, 1); |
1429 | 1306 | ||
1430 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); | 1307 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD); |
1431 | WoE_index = encode_WoE(&model, e, c2->xq_enc); | 1308 | WoE_index = encode_WoE(&model, e, c2->xq_enc); |
1432 | pack(bits, &nbit, WoE_index, WO_E_BITS); | 1309 | pack(bits, &nbit, WoE_index, WO_E_BITS); |
1433 | 1310 | ||
1434 | encode_lsps_vq(lsp_indexes, lsps, lsps_, LPC_ORD); | 1311 | encode_lsps_vq(lsp_indexes, lsps, lsps_, LPC_ORD); |
1435 | for(i=0; i<LSP_PRED_VQ_INDEXES; i++) { | 1312 | for (i = 0; i < LSP_PRED_VQ_INDEXES; i++) { |
1436 | pack(bits, &nbit, lsp_indexes[i], lsp_pred_vq_bits(i)); | 1313 | pack(bits, &nbit, lsp_indexes[i], lsp_pred_vq_bits(i)); |
1437 | } | 1314 | } |
1438 | pack(bits, &nbit, spare, 1); | 1315 | pack(bits, &nbit, spare, 1); |
1439 | 1316 | ||
1440 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 1317 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); |
1441 | } | 1318 | } |
1442 | 1319 | ||
1443 | |||
1444 | /*---------------------------------------------------------------------------*\ | 1320 | /*---------------------------------------------------------------------------*\ |
1445 | 1321 | ||
1446 | FUNCTION....: codec2_decode_1200 | 1322 | FUNCTION....: codec2_decode_1200 |
@@ -1451,494 +1327,83 @@ void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
1451 | 1327 | ||
1452 | \*---------------------------------------------------------------------------*/ | 1328 | \*---------------------------------------------------------------------------*/ |
1453 | 1329 | ||
1454 | void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 1330 | void codec2_decode_1200(struct CODEC2 *c2, short speech[], |
1455 | { | 1331 | const unsigned char *bits) { |
1456 | MODEL model[4]; | 1332 | MODEL model[4]; |
1457 | int lsp_indexes[LPC_ORD]; | 1333 | int lsp_indexes[LPC_ORD]; |
1458 | float lsps[4][LPC_ORD]; | 1334 | float lsps[4][LPC_ORD]; |
1459 | int WoE_index; | 1335 | int WoE_index; |
1460 | float e[4]; | 1336 | float e[4]; |
1461 | float snr; | 1337 | float snr; |
1462 | float ak[4][LPC_ORD+1]; | 1338 | float ak[4][LPC_ORD + 1]; |
1463 | int i,j; | 1339 | int i, j; |
1464 | unsigned int nbit = 0; | 1340 | unsigned int nbit = 0; |
1465 | float weight; | 1341 | float weight; |
1466 | COMP Aw[FFT_ENC]; | 1342 | COMP Aw[FFT_ENC]; |
1467 | 1343 | ||
1468 | assert(c2 != NULL); | 1344 | assert(c2 != NULL); |
1469 | 1345 | ||
1470 | /* only need to zero these out due to (unused) snr calculation */ | 1346 | /* only need to zero these out due to (unused) snr calculation */ |
1471 | 1347 | ||
1472 | for(i=0; i<4; i++) | 1348 | for (i = 0; i < 4; i++) |
1473 | for(j=1; j<=MAX_AMP; j++) | 1349 | for (j = 1; j <= MAX_AMP; j++) model[i].A[j] = 0.0; |
1474 | model[i].A[j] = 0.0; | 1350 | |
1475 | 1351 | /* unpack bits from channel ------------------------------------*/ | |
1476 | /* unpack bits from channel ------------------------------------*/ | 1352 | |
1477 | 1353 | /* this will partially fill the model params for the 4 x 10ms | |
1478 | /* this will partially fill the model params for the 4 x 10ms | 1354 | frames */ |
1479 | frames */ | 1355 | |
1480 | 1356 | model[0].voiced = unpack(bits, &nbit, 1); | |
1481 | model[0].voiced = unpack(bits, &nbit, 1); | 1357 | |
1482 | 1358 | model[1].voiced = unpack(bits, &nbit, 1); | |
1483 | model[1].voiced = unpack(bits, &nbit, 1); | 1359 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
1484 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 1360 | decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); |
1485 | decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index); | 1361 | |
1486 | 1362 | model[2].voiced = unpack(bits, &nbit, 1); | |
1487 | model[2].voiced = unpack(bits, &nbit, 1); | 1363 | |
1488 | 1364 | model[3].voiced = unpack(bits, &nbit, 1); | |
1489 | model[3].voiced = unpack(bits, &nbit, 1); | 1365 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
1490 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 1366 | decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); |
1491 | decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index); | 1367 | |
1492 | 1368 | for (i = 0; i < LSP_PRED_VQ_INDEXES; i++) { | |
1493 | for(i=0; i<LSP_PRED_VQ_INDEXES; i++) { | 1369 | lsp_indexes[i] = unpack(bits, &nbit, lsp_pred_vq_bits(i)); |
1494 | lsp_indexes[i] = unpack(bits, &nbit, lsp_pred_vq_bits(i)); | 1370 | } |
1495 | } | 1371 | decode_lsps_vq(lsp_indexes, &lsps[3][0], LPC_ORD, 0); |
1496 | decode_lsps_vq(lsp_indexes, &lsps[3][0], LPC_ORD , 0); | 1372 | check_lsp_order(&lsps[3][0], LPC_ORD); |
1497 | check_lsp_order(&lsps[3][0], LPC_ORD); | 1373 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); |
1498 | bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); | 1374 | |
1499 | 1375 | /* interpolate ------------------------------------------------*/ | |
1500 | /* interpolate ------------------------------------------------*/ | 1376 | |
1501 | 1377 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | |
1502 | /* Wo and energy are sampled every 20ms, so we interpolate just 1 | 1378 | 10ms frame between 20ms samples */ |
1503 | 10ms frame between 20ms samples */ | 1379 | |
1504 | 1380 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | |
1505 | interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min); | 1381 | e[0] = interp_energy(c2->prev_e_dec, e[1]); |
1506 | e[0] = interp_energy(c2->prev_e_dec, e[1]); | 1382 | interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); |
1507 | interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min); | 1383 | e[2] = interp_energy(e[1], e[3]); |
1508 | e[2] = interp_energy(e[1], e[3]); | 1384 | |
1509 | 1385 | /* LSPs are sampled every 40ms so we interpolate the 3 frames in | |
1510 | /* LSPs are sampled every 40ms so we interpolate the 3 frames in | 1386 | between, then recover spectral amplitudes */ |
1511 | between, then recover spectral amplitudes */ | 1387 | |
1512 | 1388 | for (i = 0, weight = 0.25; i < 3; i++, weight += 0.25) { | |
1513 | for(i=0, weight=0.25; i<3; i++, weight += 0.25) { | 1389 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, |
1514 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD); | 1390 | LPC_ORD); |
1515 | } | 1391 | } |
1516 | for(i=0; i<4; i++) { | 1392 | for (i = 0; i < 4; i++) { |
1517 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); | 1393 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); |
1518 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, | 1394 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, |
1519 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | 1395 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); |
1520 | apply_lpc_correction(&model[i]); | 1396 | apply_lpc_correction(&model[i]); |
1521 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | 1397 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], Aw, 1.0); |
1522 | } | 1398 | } |
1523 | 1399 | ||
1524 | /* update memories for next frame ----------------------------*/ | 1400 | /* update memories for next frame ----------------------------*/ |
1525 | 1401 | ||
1526 | c2->prev_model_dec = model[3]; | 1402 | c2->prev_model_dec = model[3]; |
1527 | c2->prev_e_dec = e[3]; | 1403 | c2->prev_e_dec = e[3]; |
1528 | for(i=0; i<LPC_ORD; i++) | 1404 | for (i = 0; i < LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; |
1529 | c2->prev_lsps_dec[i] = lsps[3][i]; | ||
1530 | } | 1405 | } |
1531 | 1406 | ||
1532 | |||
1533 | /*---------------------------------------------------------------------------*\ | ||
1534 | |||
1535 | FUNCTION....: codec2_encode_700 | ||
1536 | AUTHOR......: David Rowe | ||
1537 | DATE CREATED: April 2015 | ||
1538 | |||
1539 | Encodes 320 speech samples (40ms of speech) into 28 bits. | ||
1540 | |||
1541 | The codec2 algorithm actually operates internally on 10ms (80 | ||
1542 | sample) frames, so we run the encoding algorithm four times: | ||
1543 | |||
1544 | frame 0: nothing | ||
1545 | frame 1: nothing | ||
1546 | frame 2: nothing | ||
1547 | frame 3: voicing bit, scalar Wo and E, 17 bit LSP MEL scalar, 2 spare | ||
1548 | |||
1549 | The bit allocation is: | ||
1550 | |||
1551 | Parameter frames 1-3 frame 4 Total | ||
1552 | ----------------------------------------------------------- | ||
1553 | Harmonic magnitudes (LSPs) 0 17 17 | ||
1554 | Energy 0 3 3 | ||
1555 | log Wo 0 5 5 | ||
1556 | Voicing 0 1 1 | ||
1557 | spare 0 2 2 | ||
1558 | TOTAL 0 28 28 | ||
1559 | |||
1560 | \*---------------------------------------------------------------------------*/ | ||
1561 | |||
1562 | void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]) | ||
1563 | { | ||
1564 | MODEL model; | ||
1565 | float lsps[LPC_ORD_LOW]; | ||
1566 | float mel[LPC_ORD_LOW]; | ||
1567 | float ak[LPC_ORD_LOW+1]; | ||
1568 | float e, f; | ||
1569 | int indexes[LPC_ORD_LOW]; | ||
1570 | int Wo_index, e_index, i; | ||
1571 | unsigned int nbit = 0; | ||
1572 | float bpf_out[4*c2->n_samp]; | ||
1573 | short bpf_speech[4*c2->n_samp]; | ||
1574 | int spare = 0; | ||
1575 | |||
1576 | assert(c2 != NULL); | ||
1577 | |||
1578 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | ||
1579 | |||
1580 | /* band pass filter */ | ||
1581 | |||
1582 | for(i=0; i<BPF_N; i++) | ||
1583 | c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i]; | ||
1584 | for(i=0; i<4*c2->n_samp; i++) | ||
1585 | c2->bpf_buf[BPF_N+i] = speech[i]; | ||
1586 | inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*c2->n_samp, bpf_out, BPF_N-1); | ||
1587 | for(i=0; i<4*c2->n_samp; i++) | ||
1588 | bpf_speech[i] = bpf_out[i]; | ||
1589 | |||
1590 | /* frame 1 --------------------------------------------------------*/ | ||
1591 | |||
1592 | analyse_one_frame(c2, &model, bpf_speech); | ||
1593 | |||
1594 | /* frame 2 --------------------------------------------------------*/ | ||
1595 | |||
1596 | analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]); | ||
1597 | |||
1598 | /* frame 3 --------------------------------------------------------*/ | ||
1599 | |||
1600 | analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]); | ||
1601 | |||
1602 | /* frame 4: - voicing, scalar Wo & E, scalar LSPs -----------------*/ | ||
1603 | |||
1604 | analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]); | ||
1605 | pack(bits, &nbit, model.voiced, 1); | ||
1606 | Wo_index = encode_log_Wo(&c2->c2const, model.Wo, 5); | ||
1607 | pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray); | ||
1608 | |||
1609 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD_LOW); | ||
1610 | e_index = encode_energy(e, 3); | ||
1611 | pack_natural_or_gray(bits, &nbit, e_index, 3, c2->gray); | ||
1612 | |||
1613 | for(i=0; i<LPC_ORD_LOW; i++) { | ||
1614 | f = (4000.0/PI)*lsps[i]; | ||
1615 | mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5); | ||
1616 | } | ||
1617 | encode_mels_scalar(indexes, mel, LPC_ORD_LOW); | ||
1618 | |||
1619 | for(i=0; i<LPC_ORD_LOW; i++) { | ||
1620 | pack_natural_or_gray(bits, &nbit, indexes[i], mel_bits(i), c2->gray); | ||
1621 | } | ||
1622 | |||
1623 | pack_natural_or_gray(bits, &nbit, spare, 2, c2->gray); | ||
1624 | |||
1625 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | ||
1626 | } | ||
1627 | |||
1628 | |||
1629 | /*---------------------------------------------------------------------------*\ | ||
1630 | |||
1631 | FUNCTION....: codec2_decode_700 | ||
1632 | AUTHOR......: David Rowe | ||
1633 | DATE CREATED: April 2015 | ||
1634 | |||
1635 | Decodes frames of 28 bits into 320 samples (40ms) of speech. | ||
1636 | |||
1637 | \*---------------------------------------------------------------------------*/ | ||
1638 | |||
1639 | void codec2_decode_700(struct CODEC2 *c2, short speech[], const unsigned char * bits) | ||
1640 | { | ||
1641 | MODEL model[4]; | ||
1642 | int indexes[LPC_ORD_LOW]; | ||
1643 | float mel[LPC_ORD_LOW]; | ||
1644 | float lsps[4][LPC_ORD_LOW]; | ||
1645 | int Wo_index, e_index; | ||
1646 | float e[4]; | ||
1647 | float snr, f_; | ||
1648 | float ak[4][LPC_ORD_LOW+1]; | ||
1649 | int i,j; | ||
1650 | unsigned int nbit = 0; | ||
1651 | float weight; | ||
1652 | COMP Aw[FFT_ENC]; | ||
1653 | |||
1654 | assert(c2 != NULL); | ||
1655 | |||
1656 | /* only need to zero these out due to (unused) snr calculation */ | ||
1657 | |||
1658 | for(i=0; i<4; i++) | ||
1659 | for(j=1; j<=MAX_AMP; j++) | ||
1660 | model[i].A[j] = 0.0; | ||
1661 | |||
1662 | /* unpack bits from channel ------------------------------------*/ | ||
1663 | |||
1664 | model[3].voiced = unpack(bits, &nbit, 1); | ||
1665 | model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced; | ||
1666 | |||
1667 | Wo_index = unpack_natural_or_gray(bits, &nbit, 5, c2->gray); | ||
1668 | model[3].Wo = decode_log_Wo(&c2->c2const, Wo_index, 5); | ||
1669 | model[3].L = PI/model[3].Wo; | ||
1670 | |||
1671 | e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray); | ||
1672 | e[3] = decode_energy(e_index, 3); | ||
1673 | |||
1674 | for(i=0; i<LPC_ORD_LOW; i++) { | ||
1675 | indexes[i] = unpack_natural_or_gray(bits, &nbit, mel_bits(i), c2->gray); | ||
1676 | } | ||
1677 | |||
1678 | decode_mels_scalar(mel, indexes, LPC_ORD_LOW); | ||
1679 | for(i=0; i<LPC_ORD_LOW; i++) { | ||
1680 | f_ = 700.0*( pow(10.0, (float)mel[i]/2595.0) - 1.0); | ||
1681 | lsps[3][i] = f_*(PI/4000.0); | ||
1682 | //printf("lsps[3][%d] %f\n", i, lsps[3][i]); | ||
1683 | } | ||
1684 | |||
1685 | check_lsp_order(&lsps[3][0], LPC_ORD_LOW); | ||
1686 | bw_expand_lsps(&lsps[3][0], LPC_ORD_LOW, 50.0, 100.0); | ||
1687 | |||
1688 | #ifdef MASK_NOT_FOR_NOW | ||
1689 | /* first pass at soft decn error masking, needs further work */ | ||
1690 | /* If soft dec info available expand further for low power frames */ | ||
1691 | |||
1692 | if (c2->softdec) { | ||
1693 | float e = 0.0; | ||
1694 | for(i=9; i<9+17; i++) | ||
1695 | e += c2->softdec[i]*c2->softdec[i]; | ||
1696 | e /= 6.0; | ||
1697 | //fprintf(stderr, "e: %f\n", e); | ||
1698 | //if (e < 0.3) | ||
1699 | // bw_expand_lsps(&lsps[3][0], LPC_ORD_LOW, 150.0, 300.0); | ||
1700 | } | ||
1701 | #endif | ||
1702 | |||
1703 | /* interpolate ------------------------------------------------*/ | ||
1704 | |||
1705 | /* LSPs, Wo, and energy are sampled every 40ms so we interpolate | ||
1706 | the 3 frames in between, then recover spectral amplitudes */ | ||
1707 | |||
1708 | for(i=0, weight=0.25; i<3; i++, weight += 0.25) { | ||
1709 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD_LOW); | ||
1710 | interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min); | ||
1711 | e[i] = interp_energy2(c2->prev_e_dec, e[3],weight); | ||
1712 | } | ||
1713 | for(i=0; i<4; i++) { | ||
1714 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD_LOW); | ||
1715 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0, | ||
1716 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | ||
1717 | apply_lpc_correction(&model[i]); | ||
1718 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | ||
1719 | } | ||
1720 | |||
1721 | #ifdef DUMP | ||
1722 | dump_lsp_(&lsps[3][0]); | ||
1723 | dump_ak_(&ak[3][0], LPC_ORD_LOW); | ||
1724 | dump_model(&model[3]); | ||
1725 | if (c2->softdec) | ||
1726 | dump_softdec(c2->softdec, nbit); | ||
1727 | #endif | ||
1728 | |||
1729 | /* update memories for next frame ----------------------------*/ | ||
1730 | |||
1731 | c2->prev_model_dec = model[3]; | ||
1732 | c2->prev_e_dec = e[3]; | ||
1733 | for(i=0; i<LPC_ORD_LOW; i++) | ||
1734 | c2->prev_lsps_dec[i] = lsps[3][i]; | ||
1735 | } | ||
1736 | |||
1737 | |||
1738 | /*---------------------------------------------------------------------------*\ | ||
1739 | |||
1740 | FUNCTION....: codec2_encode_700b | ||
1741 | AUTHOR......: David Rowe | ||
1742 | DATE CREATED: August 2015 | ||
1743 | |||
1744 | Version b of 700 bit/s codec. After some experiments over the air I | ||
1745 | wanted was unhappy with the rate 700 codec so spent a few weeks | ||
1746 | trying to improve the speech quality. This version uses a wider BPF | ||
1747 | and vector quantised mel-lsps. | ||
1748 | |||
1749 | Encodes 320 speech samples (40ms of speech) into 28 bits. | ||
1750 | |||
1751 | The codec2 algorithm actually operates internally on 10ms (80 | ||
1752 | sample) frames, so we run the encoding algorithm four times: | ||
1753 | |||
1754 | frame 0: nothing | ||
1755 | frame 1: nothing | ||
1756 | frame 2: nothing | ||
1757 | frame 3: voicing bit, 5 bit scalar Wo and 3 bit E, 18 bit LSP MEL VQ, | ||
1758 | 1 spare | ||
1759 | |||
1760 | The bit allocation is: | ||
1761 | |||
1762 | Parameter frames 1-3 frame 4 Total | ||
1763 | ----------------------------------------------------------- | ||
1764 | Harmonic magnitudes (LSPs) 0 18 18 | ||
1765 | Energy 0 3 3 | ||
1766 | log Wo 0 5 5 | ||
1767 | Voicing 0 1 1 | ||
1768 | spare 0 1 1 | ||
1769 | TOTAL 0 28 28 | ||
1770 | |||
1771 | \*---------------------------------------------------------------------------*/ | ||
1772 | |||
1773 | void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]) | ||
1774 | { | ||
1775 | MODEL model; | ||
1776 | float lsps[LPC_ORD_LOW]; | ||
1777 | float mel[LPC_ORD_LOW]; | ||
1778 | float mel_[LPC_ORD_LOW]; | ||
1779 | float ak[LPC_ORD_LOW+1]; | ||
1780 | float e, f; | ||
1781 | int indexes[3]; | ||
1782 | int Wo_index, e_index, i; | ||
1783 | unsigned int nbit = 0; | ||
1784 | float bpf_out[4*c2->n_samp]; | ||
1785 | short bpf_speech[4*c2->n_samp]; | ||
1786 | int spare = 0; | ||
1787 | |||
1788 | assert(c2 != NULL); | ||
1789 | |||
1790 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | ||
1791 | |||
1792 | /* band pass filter */ | ||
1793 | |||
1794 | for(i=0; i<BPF_N; i++) | ||
1795 | c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i]; | ||
1796 | for(i=0; i<4*c2->n_samp; i++) | ||
1797 | c2->bpf_buf[BPF_N+i] = speech[i]; | ||
1798 | inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*c2->n_samp, bpf_out, BPF_N-1); | ||
1799 | for(i=0; i<4*c2->n_samp; i++) | ||
1800 | bpf_speech[i] = bpf_out[i]; | ||
1801 | |||
1802 | /* frame 1 --------------------------------------------------------*/ | ||
1803 | |||
1804 | analyse_one_frame(c2, &model, bpf_speech); | ||
1805 | |||
1806 | /* frame 2 --------------------------------------------------------*/ | ||
1807 | |||
1808 | analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]); | ||
1809 | |||
1810 | /* frame 3 --------------------------------------------------------*/ | ||
1811 | |||
1812 | analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]); | ||
1813 | |||
1814 | /* frame 4: - voicing, scalar Wo & E, VQ mel LSPs -----------------*/ | ||
1815 | |||
1816 | analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]); | ||
1817 | pack(bits, &nbit, model.voiced, 1); | ||
1818 | Wo_index = encode_log_Wo(&c2->c2const, model.Wo, 5); | ||
1819 | pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray); | ||
1820 | |||
1821 | e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD_LOW); | ||
1822 | e_index = encode_energy(e, 3); | ||
1823 | pack_natural_or_gray(bits, &nbit, e_index, 3, c2->gray); | ||
1824 | |||
1825 | for(i=0; i<LPC_ORD_LOW; i++) { | ||
1826 | f = (4000.0/PI)*lsps[i]; | ||
1827 | mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5); | ||
1828 | } | ||
1829 | lspmelvq_mbest_encode(indexes, mel, mel_, LPC_ORD_LOW, 5); | ||
1830 | |||
1831 | for(i=0; i<3; i++) { | ||
1832 | pack_natural_or_gray(bits, &nbit, indexes[i], lspmelvq_cb_bits(i), c2->gray); | ||
1833 | } | ||
1834 | |||
1835 | pack_natural_or_gray(bits, &nbit, spare, 1, c2->gray); | ||
1836 | |||
1837 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | ||
1838 | } | ||
1839 | |||
1840 | |||
1841 | /*---------------------------------------------------------------------------*\ | ||
1842 | |||
1843 | FUNCTION....: codec2_decode_700b | ||
1844 | AUTHOR......: David Rowe | ||
1845 | DATE CREATED: August 2015 | ||
1846 | |||
1847 | Decodes frames of 28 bits into 320 samples (40ms) of speech. | ||
1848 | |||
1849 | \*---------------------------------------------------------------------------*/ | ||
1850 | |||
1851 | void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * bits) | ||
1852 | { | ||
1853 | MODEL model[4]; | ||
1854 | int indexes[3]; | ||
1855 | float mel[LPC_ORD_LOW]; | ||
1856 | float lsps[4][LPC_ORD_LOW]; | ||
1857 | int Wo_index, e_index; | ||
1858 | float e[4]; | ||
1859 | float snr, f_; | ||
1860 | float ak[4][LPC_ORD_LOW+1]; | ||
1861 | int i,j; | ||
1862 | unsigned int nbit = 0; | ||
1863 | float weight; | ||
1864 | COMP Aw[FFT_ENC]; | ||
1865 | |||
1866 | assert(c2 != NULL); | ||
1867 | |||
1868 | /* only need to zero these out due to (unused) snr calculation */ | ||
1869 | |||
1870 | for(i=0; i<4; i++) | ||
1871 | for(j=1; j<=MAX_AMP; j++) | ||
1872 | model[i].A[j] = 0.0; | ||
1873 | |||
1874 | /* unpack bits from channel ------------------------------------*/ | ||
1875 | |||
1876 | model[3].voiced = unpack(bits, &nbit, 1); | ||
1877 | model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced; | ||
1878 | |||
1879 | Wo_index = unpack_natural_or_gray(bits, &nbit, 5, c2->gray); | ||
1880 | model[3].Wo = decode_log_Wo(&c2->c2const, Wo_index, 5); | ||
1881 | model[3].L = PI/model[3].Wo; | ||
1882 | |||
1883 | e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray); | ||
1884 | e[3] = decode_energy(e_index, 3); | ||
1885 | |||
1886 | for(i=0; i<3; i++) { | ||
1887 | indexes[i] = unpack_natural_or_gray(bits, &nbit, lspmelvq_cb_bits(i), c2->gray); | ||
1888 | } | ||
1889 | |||
1890 | lspmelvq_decode(indexes, mel, LPC_ORD_LOW); | ||
1891 | |||
1892 | #define MEL_ROUND 10 | ||
1893 | for(i=1; i<LPC_ORD_LOW; i++) { | ||
1894 | if (mel[i] <= mel[i-1]+MEL_ROUND) { | ||
1895 | mel[i]+=MEL_ROUND/2; | ||
1896 | mel[i-1]-=MEL_ROUND/2; | ||
1897 | i = 1; | ||
1898 | } | ||
1899 | } | ||
1900 | |||
1901 | for(i=0; i<LPC_ORD_LOW; i++) { | ||
1902 | f_ = 700.0*( pow(10.0, (float)mel[i]/2595.0) - 1.0); | ||
1903 | lsps[3][i] = f_*(PI/4000.0); | ||
1904 | //printf("lsps[3][%d] %f\n", i, lsps[3][i]); | ||
1905 | } | ||
1906 | |||
1907 | /* interpolate ------------------------------------------------*/ | ||
1908 | |||
1909 | /* LSPs, Wo, and energy are sampled every 40ms so we interpolate | ||
1910 | the 3 frames in between, then recover spectral amplitudes */ | ||
1911 | |||
1912 | for(i=0, weight=0.25; i<3; i++, weight += 0.25) { | ||
1913 | interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD_LOW); | ||
1914 | interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min); | ||
1915 | e[i] = interp_energy2(c2->prev_e_dec, e[3],weight); | ||
1916 | } | ||
1917 | for(i=0; i<4; i++) { | ||
1918 | lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD_LOW); | ||
1919 | aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0, | ||
1920 | c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); | ||
1921 | apply_lpc_correction(&model[i]); | ||
1922 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw, 1.0); | ||
1923 | } | ||
1924 | |||
1925 | #ifdef DUMP | ||
1926 | dump_lsp_(&lsps[3][0]); | ||
1927 | dump_ak_(&ak[3][0], LPC_ORD_LOW); | ||
1928 | dump_model(&model[3]); | ||
1929 | if (c2->softdec) | ||
1930 | dump_softdec(c2->softdec, nbit); | ||
1931 | #endif | ||
1932 | |||
1933 | /* update memories for next frame ----------------------------*/ | ||
1934 | |||
1935 | c2->prev_model_dec = model[3]; | ||
1936 | c2->prev_e_dec = e[3]; | ||
1937 | for(i=0; i<LPC_ORD_LOW; i++) | ||
1938 | c2->prev_lsps_dec[i] = lsps[3][i]; | ||
1939 | } | ||
1940 | |||
1941 | |||
1942 | /*---------------------------------------------------------------------------*\ | 1407 | /*---------------------------------------------------------------------------*\ |
1943 | 1408 | ||
1944 | FUNCTION....: codec2_encode_700c | 1409 | FUNCTION....: codec2_encode_700c |
@@ -1955,7 +1420,7 @@ void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * | |||
1955 | frame 0: nothing | 1420 | frame 0: nothing |
1956 | frame 1: nothing | 1421 | frame 1: nothing |
1957 | frame 2: nothing | 1422 | frame 2: nothing |
1958 | frame 3: 18 bit 2 stage VQ (9 bits/stage), 4 bits energy, | 1423 | frame 3: 18 bit 2 stage VQ (9 bits/stage), 4 bits energy, |
1959 | 6 bit scalar Wo/voicing. No spare bits. | 1424 | 6 bit scalar Wo/voicing. No spare bits. |
1960 | 1425 | ||
1961 | Voicing is encoded using the 0 index of the Wo quantiser. | 1426 | Voicing is encoded using the 0 index of the Wo quantiser. |
@@ -1971,52 +1436,54 @@ void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * | |||
1971 | 1436 | ||
1972 | \*---------------------------------------------------------------------------*/ | 1437 | \*---------------------------------------------------------------------------*/ |
1973 | 1438 | ||
1974 | void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) | 1439 | void codec2_encode_700c(struct CODEC2 *c2, unsigned char *bits, |
1975 | { | 1440 | short speech[]) { |
1976 | MODEL model; | 1441 | MODEL model; |
1977 | int indexes[4], i, M=4; | 1442 | int indexes[4], i, M = 4; |
1978 | unsigned int nbit = 0; | 1443 | unsigned int nbit = 0; |
1979 | 1444 | ||
1980 | assert(c2 != NULL); | 1445 | assert(c2 != NULL); |
1981 | 1446 | ||
1982 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | 1447 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); |
1983 | 1448 | ||
1984 | for(i=0; i<M; i++) { | 1449 | for (i = 0; i < M; i++) { |
1985 | analyse_one_frame(c2, &model, &speech[i*c2->n_samp]); | 1450 | analyse_one_frame(c2, &model, &speech[i * c2->n_samp]); |
1986 | } | 1451 | } |
1987 | 1452 | ||
1988 | int K = 20; | 1453 | int K = 20; |
1989 | float rate_K_vec[K], mean; | 1454 | float rate_K_vec[K], mean; |
1990 | float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; | 1455 | float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; |
1991 | 1456 | ||
1992 | newamp1_model_to_indexes(&c2->c2const, | 1457 | newamp1_model_to_indexes(&c2->c2const, indexes, &model, rate_K_vec, |
1993 | indexes, | 1458 | c2->rate_K_sample_freqs_kHz, K, &mean, |
1994 | &model, | 1459 | rate_K_vec_no_mean, rate_K_vec_no_mean_, &c2->se, |
1995 | rate_K_vec, | 1460 | c2->eq, c2->eq_en); |
1996 | c2->rate_K_sample_freqs_kHz, | 1461 | c2->nse += K; |
1997 | K, | ||
1998 | &mean, | ||
1999 | rate_K_vec_no_mean, | ||
2000 | rate_K_vec_no_mean_, &c2->se, c2->eq, c2->eq_en); | ||
2001 | c2->nse += K; | ||
2002 | 1462 | ||
2003 | #ifndef CORTEX_M4 | 1463 | #ifndef CORTEX_M4 |
2004 | /* dump features for deep learning experiments */ | 1464 | /* dump features for deep learning experiments */ |
2005 | if (c2->fmlfeat != NULL) { | 1465 | if (c2->fmlfeat != NULL) { |
2006 | fwrite(&mean, 1, sizeof(float), c2->fmlfeat); | 1466 | fwrite(&mean, 1, sizeof(float), c2->fmlfeat); |
2007 | fwrite(rate_K_vec_no_mean, K, sizeof(float), c2->fmlfeat); | 1467 | fwrite(rate_K_vec_no_mean, K, sizeof(float), c2->fmlfeat); |
2008 | fwrite(rate_K_vec_no_mean_, K, sizeof(float), c2->fmlfeat); | 1468 | fwrite(rate_K_vec_no_mean_, K, sizeof(float), c2->fmlfeat); |
2009 | } | 1469 | MODEL model_; |
1470 | memcpy(&model_, &model, sizeof(model)); | ||
1471 | float rate_K_vec_[K]; | ||
1472 | for (int k = 0; k < K; k++) rate_K_vec_[k] = rate_K_vec_no_mean_[k] + mean; | ||
1473 | resample_rate_L(&c2->c2const, &model_, rate_K_vec_, | ||
1474 | c2->rate_K_sample_freqs_kHz, K); | ||
1475 | fwrite(&model_.A, MAX_AMP, sizeof(float), c2->fmlfeat); | ||
1476 | } | ||
1477 | if (c2->fmlmodel != NULL) fwrite(&model, sizeof(MODEL), 1, c2->fmlmodel); | ||
2010 | #endif | 1478 | #endif |
2011 | |||
2012 | pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); | ||
2013 | pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); | ||
2014 | pack_natural_or_gray(bits, &nbit, indexes[2], 4, 0); | ||
2015 | pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); | ||
2016 | 1479 | ||
2017 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | 1480 | pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); |
2018 | } | 1481 | pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); |
1482 | pack_natural_or_gray(bits, &nbit, indexes[2], 4, 0); | ||
1483 | pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); | ||
2019 | 1484 | ||
1485 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | ||
1486 | } | ||
2020 | 1487 | ||
2021 | /*---------------------------------------------------------------------------*\ | 1488 | /*---------------------------------------------------------------------------*\ |
2022 | 1489 | ||
@@ -2028,46 +1495,53 @@ void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) | |||
2028 | 1495 | ||
2029 | \*---------------------------------------------------------------------------*/ | 1496 | \*---------------------------------------------------------------------------*/ |
2030 | 1497 | ||
2031 | void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 1498 | void codec2_decode_700c(struct CODEC2 *c2, short speech[], |
2032 | { | 1499 | const unsigned char *bits) { |
2033 | MODEL model[4]; | 1500 | MODEL model[4]; |
2034 | int indexes[4]; | 1501 | int indexes[4]; |
2035 | int i; | 1502 | int i; |
2036 | unsigned int nbit = 0; | 1503 | unsigned int nbit = 0; |
2037 | 1504 | ||
2038 | assert(c2 != NULL); | 1505 | assert(c2 != NULL); |
2039 | 1506 | ||
2040 | /* unpack bits from channel ------------------------------------*/ | 1507 | /* unpack bits from channel ------------------------------------*/ |
2041 | 1508 | ||
2042 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); | 1509 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); |
2043 | indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); | 1510 | indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); |
2044 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); | 1511 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); |
2045 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); | 1512 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); |
2046 | 1513 | ||
2047 | int M = 4; | 1514 | int M = 4; |
2048 | COMP HH[M][MAX_AMP+1]; | 1515 | COMP HH[M][MAX_AMP + 1]; |
2049 | float interpolated_surface_[M][NEWAMP1_K]; | 1516 | float interpolated_surface_[M][NEWAMP1_K]; |
2050 | 1517 | ||
2051 | newamp1_indexes_to_model(&c2->c2const, | 1518 | newamp1_indexes_to_model( |
2052 | model, | 1519 | &c2->c2const, model, (COMP *)HH, (float *)interpolated_surface_, |
2053 | (COMP*)HH, | 1520 | c2->prev_rate_K_vec_, &c2->Wo_left, &c2->voicing_left, |
2054 | (float*)interpolated_surface_, | 1521 | c2->rate_K_sample_freqs_kHz, NEWAMP1_K, c2->phase_fft_fwd_cfg, |
2055 | c2->prev_rate_K_vec_, | 1522 | c2->phase_fft_inv_cfg, indexes, c2->user_rate_K_vec_no_mean_, |
2056 | &c2->Wo_left, | 1523 | c2->post_filter_en); |
2057 | &c2->voicing_left, | 1524 | |
2058 | c2->rate_K_sample_freqs_kHz, | 1525 | for (i = 0; i < M; i++) { |
2059 | NEWAMP1_K, | 1526 | if (c2->fmlfeat != NULL) { |
2060 | c2->phase_fft_fwd_cfg, | 1527 | /* We use standard nb_features=55 feature records for compatibility with |
2061 | c2->phase_fft_inv_cfg, | 1528 | * train_lpcnet.py */ |
2062 | indexes, | 1529 | float features[55] = {0}; |
2063 | c2->user_rate_K_vec_no_mean_, | 1530 | /* just using 18/20 for compatibility with LPCNet, coarse scaling for NN |
2064 | c2->post_filter_en); | 1531 | * input */ |
2065 | 1532 | for (int j = 0; j < 18; j++) | |
2066 | 1533 | features[j] = (interpolated_surface_[i][j] - 30) / 40; | |
2067 | for(i=0; i<M; i++) { | 1534 | int pitch_index = 21 + 2.0 * M_PI / model[i].Wo; |
2068 | /* 700C is a little quiter so lets apply some experimentally derived audio gain */ | 1535 | features[36] = 0.02 * (pitch_index - 100); |
2069 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], &HH[i][0], 1.5); | 1536 | features[37] = model[i].voiced; |
2070 | } | 1537 | fwrite(features, 55, sizeof(float), c2->fmlfeat); |
1538 | } | ||
1539 | |||
1540 | /* 700C is a little quieter so lets apply some experimentally derived audio | ||
1541 | * gain */ | ||
1542 | synthesise_one_frame(c2, &speech[c2->n_samp * i], &model[i], &HH[i][0], | ||
1543 | 1.5); | ||
1544 | } | ||
2071 | } | 1545 | } |
2072 | 1546 | ||
2073 | /*---------------------------------------------------------------------------*\ | 1547 | /*---------------------------------------------------------------------------*\ |
@@ -2080,48 +1554,24 @@ void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * | |||
2080 | 1554 | ||
2081 | \*---------------------------------------------------------------------------*/ | 1555 | \*---------------------------------------------------------------------------*/ |
2082 | 1556 | ||
2083 | float codec2_energy_700c(struct CODEC2 *c2, const unsigned char * bits) | 1557 | float codec2_energy_700c(struct CODEC2 *c2, const unsigned char *bits) { |
2084 | { | 1558 | int indexes[4]; |
2085 | int indexes[4]; | 1559 | unsigned int nbit = 0; |
2086 | unsigned int nbit = 0; | ||
2087 | 1560 | ||
2088 | assert(c2 != NULL); | 1561 | assert(c2 != NULL); |
2089 | 1562 | ||
2090 | /* unpack bits from channel ------------------------------------*/ | 1563 | /* unpack bits from channel ------------------------------------*/ |
2091 | 1564 | ||
2092 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); | 1565 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); |
2093 | indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); | 1566 | indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); |
2094 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); | 1567 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0); |
2095 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); | 1568 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); |
2096 | 1569 | ||
2097 | float mean = newamp1_energy_cb[0].cb[indexes[2]]; | 1570 | float mean = newamp1_energy_cb[0].cb[indexes[2]]; |
2098 | mean -= 10; | 1571 | mean -= 10; |
2099 | if (indexes[3] == 0) | 1572 | if (indexes[3] == 0) mean -= 10; |
2100 | mean -= 10; | ||
2101 | 1573 | ||
2102 | return POW10F(mean/10.0); | 1574 | return POW10F(mean / 10.0); |
2103 | } | ||
2104 | |||
2105 | float codec2_energy_450(struct CODEC2 *c2, const unsigned char * bits) | ||
2106 | { | ||
2107 | int indexes[4]; | ||
2108 | unsigned int nbit = 0; | ||
2109 | |||
2110 | assert(c2 != NULL); | ||
2111 | |||
2112 | /* unpack bits from channel ------------------------------------*/ | ||
2113 | |||
2114 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); | ||
2115 | //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); | ||
2116 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); | ||
2117 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); | ||
2118 | |||
2119 | float mean = newamp2_energy_cb[0].cb[indexes[2]]; | ||
2120 | mean -= 10; | ||
2121 | if (indexes[3] == 0) | ||
2122 | mean -= 10; | ||
2123 | |||
2124 | return POW10F(mean/10.0); | ||
2125 | } | 1575 | } |
2126 | 1576 | ||
2127 | /*---------------------------------------------------------------------------*\ | 1577 | /*---------------------------------------------------------------------------*\ |
@@ -2134,300 +1584,58 @@ float codec2_energy_450(struct CODEC2 *c2, const unsigned char * bits) | |||
2134 | 1584 | ||
2135 | \*---------------------------------------------------------------------------*/ | 1585 | \*---------------------------------------------------------------------------*/ |
2136 | 1586 | ||
2137 | float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) | 1587 | float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits) { |
2138 | { | 1588 | assert(c2 != NULL); |
2139 | assert(c2 != NULL); | 1589 | assert((CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) || |
2140 | assert( | 1590 | (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) || |
2141 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) || | 1591 | (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) || |
2142 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) || | 1592 | (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) || |
2143 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) || | 1593 | (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) || |
2144 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) || | 1594 | (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) || |
2145 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) || | 1595 | (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode))); |
2146 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) || | 1596 | MODEL model; |
2147 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700, c2->mode)) || | 1597 | float xq_dec[2] = {}; |
2148 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, c2->mode)) || | 1598 | int e_index, WoE_index; |
2149 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) || | 1599 | float e = 0.0f; |
2150 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode)) || | 1600 | unsigned int nbit; |
2151 | ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) | 1601 | |
2152 | ); | 1602 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) { |
2153 | MODEL model; | 1603 | nbit = 1 + 1 + WO_BITS; |
2154 | float xq_dec[2] = {}; | 1604 | e_index = unpack(bits, &nbit, E_BITS); |
2155 | int e_index, WoE_index; | 1605 | e = decode_energy(e_index, E_BITS); |
2156 | float e; | 1606 | } |
2157 | unsigned int nbit; | 1607 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) { |
2158 | 1608 | nbit = 1 + 1; | |
2159 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_3200, c2->mode)) { | 1609 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
2160 | nbit = 1 + 1 + WO_BITS; | 1610 | decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); |
2161 | e_index = unpack(bits, &nbit, E_BITS); | 1611 | } |
2162 | e = decode_energy(e_index, E_BITS); | 1612 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) { |
2163 | } | 1613 | nbit = 1 + 1 + WO_BITS; |
2164 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_2400, c2->mode)) { | 1614 | e_index = unpack(bits, &nbit, E_BITS); |
2165 | nbit = 1 + 1; | 1615 | e = decode_energy(e_index, E_BITS); |
2166 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 1616 | } |
2167 | decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); | 1617 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) { |
2168 | } | 1618 | nbit = 1 + 1; |
2169 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1600, c2->mode)) { | 1619 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
2170 | nbit = 1 + 1 + WO_BITS; | 1620 | decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); |
2171 | e_index = unpack(bits, &nbit, E_BITS); | 1621 | } |
2172 | e = decode_energy(e_index, E_BITS); | 1622 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) { |
2173 | } | 1623 | nbit = 1 + 1 + 1 + 1 + WO_BITS; |
2174 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1400, c2->mode)) { | 1624 | e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); |
2175 | nbit = 1 + 1; | 1625 | e = decode_energy(e_index, E_BITS); |
2176 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | 1626 | } |
2177 | decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); | 1627 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) { |
2178 | } | 1628 | nbit = 1 + 1; |
2179 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1300, c2->mode)) { | 1629 | WoE_index = unpack(bits, &nbit, WO_E_BITS); |
2180 | nbit = 1 + 1 + 1 + 1 + WO_BITS; | 1630 | decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); |
2181 | e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray); | 1631 | } |
2182 | e = decode_energy(e_index, E_BITS); | 1632 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { |
2183 | } | 1633 | e = codec2_energy_700c(c2, bits); |
2184 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_1200, c2->mode)) { | 1634 | } |
2185 | nbit = 1 + 1; | ||
2186 | WoE_index = unpack(bits, &nbit, WO_E_BITS); | ||
2187 | decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index); | ||
2188 | } | ||
2189 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700, c2->mode)) { | ||
2190 | nbit = 1 + 5; | ||
2191 | e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray); | ||
2192 | e = decode_energy(e_index, 3); | ||
2193 | } | ||
2194 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700B, c2->mode)) { | ||
2195 | nbit = 1 + 5; | ||
2196 | e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray); | ||
2197 | e = decode_energy(e_index, 3); | ||
2198 | } | ||
2199 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { | ||
2200 | e = codec2_energy_700c(c2, bits); | ||
2201 | } | ||
2202 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode)) { | ||
2203 | e = codec2_energy_450(c2, bits); | ||
2204 | } | ||
2205 | |||
2206 | return e; | ||
2207 | } | ||
2208 | |||
2209 | |||
2210 | /*---------------------------------------------------------------------------*\ | ||
2211 | |||
2212 | FUNCTION....: codec2_encode_450 | ||
2213 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
2214 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
2215 | DATE CREATED: July 2018 | ||
2216 | |||
2217 | 450 bit/s codec that uses newamp2 fixed rate VQ of amplitudes. | ||
2218 | |||
2219 | Encodes 320 speech samples (40ms of speech) into 28 bits. | ||
2220 | |||
2221 | The codec2 algorithm actually operates internally on 10ms (80 | ||
2222 | sample) frames, so we run the encoding algorithm four times: | ||
2223 | |||
2224 | frame 0: nothing | ||
2225 | frame 1: nothing | ||
2226 | frame 2: nothing | ||
2227 | frame 3: 9 bit 1 stage VQ, 3 bits energy, | ||
2228 | 6 bit scalar Wo/voicing/plosive. No spare bits. | ||
2229 | |||
2230 | If a plosive is detected the frame at the energy-step is encoded. | ||
2231 | |||
2232 | Voicing is encoded using the 000000 index of the Wo quantiser. | ||
2233 | Plosive is encoded using the 111111 index of the Wo quantiser. | ||
2234 | |||
2235 | The bit allocation is: | ||
2236 | |||
2237 | Parameter frames 1-3 frame 4 Total | ||
2238 | ----------------------------------------------------------- | ||
2239 | Harmonic magnitudes (rate k VQ) 0 9 9 | ||
2240 | Energy 0 3 3 | ||
2241 | log Wo/voicing/plosive 0 6 6 | ||
2242 | TOTAL 0 18 18 | ||
2243 | |||
2244 | |||
2245 | \*---------------------------------------------------------------------------*/ | ||
2246 | |||
2247 | void codec2_encode_450(struct CODEC2 *c2, unsigned char * bits, short speech[]) | ||
2248 | { | ||
2249 | MODEL model; | ||
2250 | int indexes[4], i,h, M=4; | ||
2251 | unsigned int nbit = 0; | ||
2252 | int plosiv = 0; | ||
2253 | float energydelta[M]; | ||
2254 | int spectralCounter; | ||
2255 | |||
2256 | assert(c2 != NULL); | ||
2257 | |||
2258 | memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); | ||
2259 | for(i=0; i<M; i++){ | ||
2260 | analyse_one_frame(c2, &model, &speech[i*c2->n_samp]); | ||
2261 | energydelta[i] = 0; | ||
2262 | spectralCounter = 0; | ||
2263 | for(h = 0;h<(model.L);h++){ | ||
2264 | //only detect above 300 Hz | ||
2265 | if(h*model.Wo*(c2->c2const.Fs/2000.0)/M_PI > 0.3){ | ||
2266 | energydelta[i] = energydelta[i] + 20.0*log10(model.A[10]+1E-16); | ||
2267 | spectralCounter = spectralCounter+1; | ||
2268 | } | ||
2269 | |||
2270 | } | ||
2271 | energydelta[i] = energydelta[i] / spectralCounter ; | ||
2272 | } | ||
2273 | //Constants for plosive Detection tdB = threshold; minPwr = from below this level plosives have to rise | ||
2274 | float tdB = 15; //not fixed can be changed | ||
2275 | float minPwr = 15; //not fixed can be changed | ||
2276 | if((c2->energy_prev)<minPwr && energydelta[0]>((c2->energy_prev)+tdB)){ | ||
2277 | |||
2278 | plosiv = 1; | ||
2279 | } | ||
2280 | if(energydelta[0]<minPwr && energydelta[1]>(energydelta[0]+tdB)){ | ||
2281 | |||
2282 | plosiv = 2; | ||
2283 | } | ||
2284 | if(energydelta[1]<minPwr &&energydelta[2]>(energydelta[1]+tdB)){ | ||
2285 | |||
2286 | plosiv = 3; | ||
2287 | } | ||
2288 | if(energydelta[2]<minPwr &&energydelta[3]>(energydelta[2]+tdB)){ | ||
2289 | |||
2290 | plosiv = 4; | ||
2291 | } | ||
2292 | if(plosiv != 0 && plosiv != 4){ | ||
2293 | analyse_one_frame(c2, &model, &speech[(plosiv-1)*c2->n_samp]); | ||
2294 | } | ||
2295 | |||
2296 | c2->energy_prev = energydelta[3]; | ||
2297 | |||
2298 | |||
2299 | int K = 29; | ||
2300 | float rate_K_vec[K], mean; | ||
2301 | float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; | ||
2302 | if(plosiv > 0){ | ||
2303 | plosiv = 1; | ||
2304 | } | ||
2305 | newamp2_model_to_indexes(&c2->c2const, | ||
2306 | indexes, | ||
2307 | &model, | ||
2308 | rate_K_vec, | ||
2309 | c2->n2_rate_K_sample_freqs_kHz, | ||
2310 | K, | ||
2311 | &mean, | ||
2312 | rate_K_vec_no_mean, | ||
2313 | rate_K_vec_no_mean_, | ||
2314 | plosiv); | ||
2315 | |||
2316 | |||
2317 | pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0); | ||
2318 | //pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0); | ||
2319 | pack_natural_or_gray(bits, &nbit, indexes[2], 3, 0); | ||
2320 | pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0); | ||
2321 | |||
2322 | assert(nbit == (unsigned)codec2_bits_per_frame(c2)); | ||
2323 | } | ||
2324 | |||
2325 | |||
2326 | /*---------------------------------------------------------------------------*\ | ||
2327 | |||
2328 | FUNCTION....: codec2_decode_450 | ||
2329 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
2330 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
2331 | DATE CREATED: July 2018 | ||
2332 | |||
2333 | \*---------------------------------------------------------------------------*/ | ||
2334 | |||
2335 | void codec2_decode_450(struct CODEC2 *c2, short speech[], const unsigned char * bits) | ||
2336 | { | ||
2337 | MODEL model[4]; | ||
2338 | int indexes[4]; | ||
2339 | int i; | ||
2340 | unsigned int nbit = 0; | ||
2341 | |||
2342 | assert(c2 != NULL); | ||
2343 | |||
2344 | /* unpack bits from channel ------------------------------------*/ | ||
2345 | |||
2346 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); | ||
2347 | //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); | ||
2348 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); | ||
2349 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); | ||
2350 | |||
2351 | int M = 4; | ||
2352 | COMP HH[M][MAX_AMP+1]; | ||
2353 | float interpolated_surface_[M][NEWAMP2_K]; | ||
2354 | int pwbFlag = 0; | ||
2355 | |||
2356 | newamp2_indexes_to_model(&c2->c2const, | ||
2357 | model, | ||
2358 | (COMP*)HH, | ||
2359 | (float*)interpolated_surface_, | ||
2360 | c2->n2_prev_rate_K_vec_, | ||
2361 | &c2->Wo_left, | ||
2362 | &c2->voicing_left, | ||
2363 | c2->n2_rate_K_sample_freqs_kHz, | ||
2364 | NEWAMP2_K, | ||
2365 | c2->phase_fft_fwd_cfg, | ||
2366 | c2->phase_fft_inv_cfg, | ||
2367 | indexes, | ||
2368 | 1.5, | ||
2369 | pwbFlag); | ||
2370 | |||
2371 | |||
2372 | for(i=0; i<M; i++) { | ||
2373 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], &HH[i][0], 1.5); | ||
2374 | } | ||
2375 | } | ||
2376 | |||
2377 | /*---------------------------------------------------------------------------*\ | ||
2378 | |||
2379 | FUNCTION....: codec2_decode_450pwb | ||
2380 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
2381 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
2382 | DATE CREATED: July 2018 | ||
2383 | |||
2384 | Decodes the 450 codec data in pseudo wideband at 16kHz samplerate. | ||
2385 | |||
2386 | \*---------------------------------------------------------------------------*/ | ||
2387 | 1635 | ||
2388 | void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char * bits) | 1636 | return e; |
2389 | { | ||
2390 | MODEL model[4]; | ||
2391 | int indexes[4]; | ||
2392 | int i; | ||
2393 | unsigned int nbit = 0; | ||
2394 | |||
2395 | assert(c2 != NULL); | ||
2396 | |||
2397 | /* unpack bits from channel ------------------------------------*/ | ||
2398 | |||
2399 | indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0); | ||
2400 | //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0); | ||
2401 | indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0); | ||
2402 | indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0); | ||
2403 | |||
2404 | int M = 4; | ||
2405 | COMP HH[M][MAX_AMP+1]; | ||
2406 | float interpolated_surface_[M][NEWAMP2_16K_K]; | ||
2407 | int pwbFlag = 1; | ||
2408 | |||
2409 | newamp2_indexes_to_model(&c2->c2const, | ||
2410 | model, | ||
2411 | (COMP*)HH, | ||
2412 | (float*)interpolated_surface_, | ||
2413 | c2->n2_pwb_prev_rate_K_vec_, | ||
2414 | &c2->Wo_left, | ||
2415 | &c2->voicing_left, | ||
2416 | c2->n2_pwb_rate_K_sample_freqs_kHz, | ||
2417 | NEWAMP2_16K_K, | ||
2418 | c2->phase_fft_fwd_cfg, | ||
2419 | c2->phase_fft_inv_cfg, | ||
2420 | indexes, | ||
2421 | 1.5, | ||
2422 | pwbFlag); | ||
2423 | |||
2424 | |||
2425 | for(i=0; i<M; i++) { | ||
2426 | synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], &HH[i][0], 1.5); | ||
2427 | } | ||
2428 | } | 1637 | } |
2429 | 1638 | ||
2430 | |||
2431 | /*---------------------------------------------------------------------------* \ | 1639 | /*---------------------------------------------------------------------------* \ |
2432 | 1640 | ||
2433 | FUNCTION....: synthesise_one_frame() | 1641 | FUNCTION....: synthesise_one_frame() |
@@ -2438,56 +1646,41 @@ void codec2_decode_450pwb(struct CODEC2 *c2, short speech[], const unsigned char | |||
2438 | 1646 | ||
2439 | \*---------------------------------------------------------------------------*/ | 1647 | \*---------------------------------------------------------------------------*/ |
2440 | 1648 | ||
2441 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP Aw[], float gain) | 1649 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, |
2442 | { | 1650 | COMP Aw[], float gain) { |
2443 | int i; | 1651 | int i; |
2444 | //PROFILE_VAR(phase_start, pf_start, synth_start); | 1652 | |
2445 | 1653 | if (CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode)) { | |
2446 | //#ifdef DUMP | 1654 | /* newamp1, we've already worked out rate L phase */ |
2447 | //dump_quantised_model(model); | 1655 | COMP *H = Aw; |
2448 | //#endif | 1656 | phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); |
2449 | 1657 | } else { | |
2450 | //PROFILE_SAMPLE(phase_start); | 1658 | /* LPC based phase synthesis */ |
2451 | 1659 | COMP H[MAX_AMP + 1]; | |
2452 | if ( CODEC2_MODE_ACTIVE(CODEC2_MODE_700C, c2->mode) || CODEC2_MODE_ACTIVE(CODEC2_MODE_450, c2->mode) || CODEC2_MODE_ACTIVE(CODEC2_MODE_450PWB, c2->mode) ) { | 1660 | sample_phase(model, H, Aw); |
2453 | /* newamp1/2, we've already worked out rate L phase */ | 1661 | phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); |
2454 | COMP *H = Aw; | 1662 | } |
2455 | phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); | 1663 | |
2456 | } else { | 1664 | postfilter(model, &c2->bg_est); |
2457 | /* LPC based phase synthesis */ | 1665 | synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); |
2458 | COMP H[MAX_AMP+1]; | 1666 | |
2459 | sample_phase(model, H, Aw); | 1667 | for (i = 0; i < c2->n_samp; i++) { |
2460 | phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); | 1668 | c2->Sn_[i] *= gain; |
2461 | } | 1669 | } |
2462 | 1670 | ||
2463 | //PROFILE_SAMPLE_AND_LOG(pf_start, phase_start, " phase_synth"); | 1671 | ear_protection(c2->Sn_, c2->n_samp); |
2464 | 1672 | ||
2465 | postfilter(model, &c2->bg_est); | 1673 | for (i = 0; i < c2->n_samp; i++) { |
2466 | 1674 | if (c2->Sn_[i] > 32767.0) | |
2467 | //PROFILE_SAMPLE_AND_LOG(synth_start, pf_start, " postfilter"); | 1675 | speech[i] = 32767; |
2468 | 1676 | else if (c2->Sn_[i] < -32767.0) | |
2469 | synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); | 1677 | speech[i] = -32767; |
2470 | 1678 | else | |
2471 | for(i=0; i<c2->n_samp; i++) { | 1679 | speech[i] = c2->Sn_[i]; |
2472 | c2->Sn_[i] *= gain; | 1680 | } |
2473 | } | ||
2474 | |||
2475 | //PROFILE_SAMPLE_AND_LOG2(synth_start, " synth"); | ||
2476 | |||
2477 | ear_protection(c2->Sn_, c2->n_samp); | ||
2478 | |||
2479 | for(i=0; i<c2->n_samp; i++) { | ||
2480 | if (c2->Sn_[i] > 32767.0) | ||
2481 | speech[i] = 32767; | ||
2482 | else if (c2->Sn_[i] < -32767.0) | ||
2483 | speech[i] = -32767; | ||
2484 | else | ||
2485 | speech[i] = c2->Sn_[i]; | ||
2486 | } | ||
2487 | |||
2488 | } | 1681 | } |
2489 | 1682 | ||
2490 | /*---------------------------------------------------------------------------*\ | 1683 | /*---------------------------------------------------------------------------* \ |
2491 | 1684 | ||
2492 | FUNCTION....: analyse_one_frame() | 1685 | FUNCTION....: analyse_one_frame() |
2493 | AUTHOR......: David Rowe | 1686 | AUTHOR......: David Rowe |
@@ -2498,48 +1691,40 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP | |||
2498 | 1691 | ||
2499 | \*---------------------------------------------------------------------------*/ | 1692 | \*---------------------------------------------------------------------------*/ |
2500 | 1693 | ||
2501 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) | 1694 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) { |
2502 | { | 1695 | COMP Sw[FFT_ENC]; |
2503 | COMP Sw[FFT_ENC]; | 1696 | float pitch; |
2504 | float pitch; | 1697 | int i; |
2505 | int i; | 1698 | int n_samp = c2->n_samp; |
2506 | //PROFILE_VAR(dft_start, nlp_start, model_start, two_stage, estamps); | 1699 | int m_pitch = c2->m_pitch; |
2507 | int n_samp = c2->n_samp; | ||
2508 | int m_pitch = c2->m_pitch; | ||
2509 | 1700 | ||
2510 | /* Read input speech */ | 1701 | /* Read input speech */ |
2511 | 1702 | ||
2512 | for(i=0; i<m_pitch-n_samp; i++) | 1703 | for (i = 0; i < m_pitch - n_samp; i++) c2->Sn[i] = c2->Sn[i + n_samp]; |
2513 | c2->Sn[i] = c2->Sn[i+n_samp]; | 1704 | for (i = 0; i < n_samp; i++) c2->Sn[i + m_pitch - n_samp] = speech[i]; |
2514 | for(i=0; i<n_samp; i++) | ||
2515 | c2->Sn[i+m_pitch-n_samp] = speech[i]; | ||
2516 | 1705 | ||
2517 | //PROFILE_SAMPLE(dft_start); | 1706 | dft_speech(&c2->c2const, c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); |
2518 | dft_speech(&c2->c2const, c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); | ||
2519 | //PROFILE_SAMPLE_AND_LOG(nlp_start, dft_start, " dft_speech"); | ||
2520 | 1707 | ||
2521 | /* Estimate pitch */ | 1708 | /* Estimate pitch */ |
1709 | nlp(c2->nlp, c2->Sn, n_samp, &pitch, Sw, c2->W, &c2->prev_f0_enc); | ||
1710 | model->Wo = TWO_PI / pitch; | ||
1711 | model->L = PI / model->Wo; | ||
2522 | 1712 | ||
2523 | nlp(c2->nlp, c2->Sn, n_samp, &pitch, Sw, c2->W, &c2->prev_f0_enc); | 1713 | /* estimate model parameters */ |
2524 | //PROFILE_SAMPLE_AND_LOG(model_start, nlp_start, " nlp"); | 1714 | two_stage_pitch_refinement(&c2->c2const, model, Sw); |
2525 | 1715 | ||
2526 | model->Wo = TWO_PI/pitch; | 1716 | /* estimate phases when doing ML experiments */ |
2527 | model->L = PI/model->Wo; | 1717 | if (c2->fmlfeat != NULL) |
2528 | 1718 | estimate_amplitudes(model, Sw, c2->W, 1); | |
2529 | /* estimate model parameters */ | 1719 | else |
2530 | |||
2531 | two_stage_pitch_refinement(&c2->c2const, model, Sw); | ||
2532 | //PROFILE_SAMPLE_AND_LOG(two_stage, model_start, " two_stage"); | ||
2533 | estimate_amplitudes(model, Sw, c2->W, 0); | 1720 | estimate_amplitudes(model, Sw, c2->W, 0); |
2534 | //PROFILE_SAMPLE_AND_LOG(estamps, two_stage, " est_amps"); | 1721 | est_voicing_mbe(&c2->c2const, model, Sw, c2->W); |
2535 | est_voicing_mbe(&c2->c2const, model, Sw, c2->W); | 1722 | #ifdef DUMP |
2536 | //PROFILE_SAMPLE_AND_LOG2(estamps, " est_voicing"); | 1723 | dump_model(model); |
2537 | #ifdef DUMP | 1724 | #endif |
2538 | dump_model(model); | ||
2539 | #endif | ||
2540 | } | 1725 | } |
2541 | 1726 | ||
2542 | /*---------------------------------------------------------------------------*\ | 1727 | /*---------------------------------------------------------------------------* \ |
2543 | 1728 | ||
2544 | FUNCTION....: ear_protection() | 1729 | FUNCTION....: ear_protection() |
2545 | AUTHOR......: David Rowe | 1730 | AUTHOR......: David Rowe |
@@ -2552,40 +1737,37 @@ void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) | |||
2552 | \*---------------------------------------------------------------------------*/ | 1737 | \*---------------------------------------------------------------------------*/ |
2553 | 1738 | ||
2554 | static void ear_protection(float in_out[], int n) { | 1739 | static void ear_protection(float in_out[], int n) { |
2555 | float max_sample, over, gain; | 1740 | float max_sample, over, gain; |
2556 | int i; | 1741 | int i; |
2557 | 1742 | ||
2558 | /* find maximum sample in frame */ | 1743 | /* find maximum sample in frame */ |
2559 | 1744 | ||
2560 | max_sample = 0.0; | 1745 | max_sample = 0.0; |
2561 | for(i=0; i<n; i++) | 1746 | for (i = 0; i < n; i++) |
2562 | if (in_out[i] > max_sample) | 1747 | if (in_out[i] > max_sample) max_sample = in_out[i]; |
2563 | max_sample = in_out[i]; | ||
2564 | 1748 | ||
2565 | /* determine how far above set point */ | 1749 | /* determine how far above set point */ |
2566 | 1750 | ||
2567 | over = max_sample/30000.0; | 1751 | over = max_sample / 30000.0; |
2568 | 1752 | ||
2569 | /* If we are x dB over set point we reduce level by 2x dB, this | 1753 | /* If we are x dB over set point we reduce level by 2x dB, this |
2570 | attenuates major excursions in amplitude (likely to be caused | 1754 | attenuates major excursions in amplitude (likely to be caused |
2571 | by bit errors) more than smaller ones */ | 1755 | by bit errors) more than smaller ones */ |
2572 | 1756 | ||
2573 | if (over > 1.0) { | 1757 | if (over > 1.0) { |
2574 | gain = 1.0/(over*over); | 1758 | gain = 1.0 / (over * over); |
2575 | //fprintf(stderr, "gain: %f\n", gain); | 1759 | for (i = 0; i < n; i++) in_out[i] *= gain; |
2576 | for(i=0; i<n; i++) | 1760 | } |
2577 | in_out[i] *= gain; | ||
2578 | } | ||
2579 | } | 1761 | } |
2580 | 1762 | ||
2581 | void codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, float beta, float gamma) | 1763 | void codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, |
2582 | { | 1764 | float beta, float gamma) { |
2583 | assert((beta >= 0.0) && (beta <= 1.0)); | 1765 | assert((beta >= 0.0) && (beta <= 1.0)); |
2584 | assert((gamma >= 0.0) && (gamma <= 1.0)); | 1766 | assert((gamma >= 0.0) && (gamma <= 1.0)); |
2585 | c2->lpc_pf = enable; | 1767 | c2->lpc_pf = enable; |
2586 | c2->bass_boost = bass_boost; | 1768 | c2->bass_boost = bass_boost; |
2587 | c2->beta = beta; | 1769 | c2->beta = beta; |
2588 | c2->gamma = gamma; | 1770 | c2->gamma = gamma; |
2589 | } | 1771 | } |
2590 | 1772 | ||
2591 | /* | 1773 | /* |
@@ -2594,29 +1776,22 @@ void codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, f | |||
2594 | Experimental method of sending voice/data frames for FreeDV. | 1776 | Experimental method of sending voice/data frames for FreeDV. |
2595 | */ | 1777 | */ |
2596 | 1778 | ||
2597 | int codec2_get_spare_bit_index(struct CODEC2 *c2) | 1779 | int codec2_get_spare_bit_index(struct CODEC2 *c2) { |
2598 | { | 1780 | assert(c2 != NULL); |
2599 | assert(c2 != NULL); | ||
2600 | 1781 | ||
2601 | switch(c2->mode) { | 1782 | switch (c2->mode) { |
2602 | case CODEC2_MODE_1300: | 1783 | case CODEC2_MODE_1300: |
2603 | return 2; // bit 2 (3th bit) is v2 (third voicing bit) | 1784 | return 2; // bit 2 (3th bit) is v2 (third voicing bit) |
2604 | break; | 1785 | break; |
2605 | case CODEC2_MODE_1400: | 1786 | case CODEC2_MODE_1400: |
2606 | return 10; // bit 10 (11th bit) is v2 (third voicing bit) | 1787 | return 10; // bit 10 (11th bit) is v2 (third voicing bit) |
2607 | break; | 1788 | break; |
2608 | case CODEC2_MODE_1600: | 1789 | case CODEC2_MODE_1600: |
2609 | return 15; // bit 15 (16th bit) is v2 (third voicing bit) | 1790 | return 15; // bit 15 (16th bit) is v2 (third voicing bit) |
2610 | break; | 1791 | break; |
2611 | case CODEC2_MODE_700: | 1792 | } |
2612 | return 26; // bits 26 and 27 are spare | ||
2613 | break; | ||
2614 | case CODEC2_MODE_700B: | ||
2615 | return 27; // bit 27 is spare | ||
2616 | break; | ||
2617 | } | ||
2618 | 1793 | ||
2619 | return -1; | 1794 | return -1; |
2620 | } | 1795 | } |
2621 | 1796 | ||
2622 | /* | 1797 | /* |
@@ -2624,111 +1799,123 @@ int codec2_get_spare_bit_index(struct CODEC2 *c2) | |||
2624 | for convenience. | 1799 | for convenience. |
2625 | */ | 1800 | */ |
2626 | 1801 | ||
2627 | int codec2_rebuild_spare_bit(struct CODEC2 *c2, int unpacked_bits[]) | 1802 | int codec2_rebuild_spare_bit(struct CODEC2 *c2, char unpacked_bits[]) { |
2628 | { | 1803 | int v1, v3; |
2629 | int v1,v3; | ||
2630 | 1804 | ||
2631 | assert(c2 != NULL); | 1805 | assert(c2 != NULL); |
2632 | 1806 | ||
2633 | v1 = unpacked_bits[1]; | 1807 | v1 = unpacked_bits[1]; |
2634 | 1808 | ||
2635 | switch(c2->mode) { | 1809 | switch (c2->mode) { |
2636 | case CODEC2_MODE_1300: | 1810 | case CODEC2_MODE_1300: |
2637 | 1811 | ||
2638 | v3 = unpacked_bits[1+1+1]; | 1812 | v3 = unpacked_bits[1 + 1 + 1]; |
2639 | 1813 | ||
2640 | /* if either adjacent frame is voiced, make this one voiced */ | 1814 | /* if either adjacent frame is voiced, make this one voiced */ |
2641 | 1815 | ||
2642 | unpacked_bits[2] = (v1 || v3); | 1816 | unpacked_bits[2] = (v1 || v3); |
2643 | 1817 | ||
2644 | return 0; | 1818 | return 0; |
2645 | 1819 | ||
2646 | break; | 1820 | break; |
2647 | 1821 | ||
2648 | case CODEC2_MODE_1400: | 1822 | case CODEC2_MODE_1400: |
2649 | 1823 | ||
2650 | v3 = unpacked_bits[1+1+8+1]; | 1824 | v3 = unpacked_bits[1 + 1 + 8 + 1]; |
2651 | 1825 | ||
2652 | /* if either adjacent frame is voiced, make this one voiced */ | 1826 | /* if either adjacent frame is voiced, make this one voiced */ |
2653 | 1827 | ||
2654 | unpacked_bits[10] = (v1 || v3); | 1828 | unpacked_bits[10] = (v1 || v3); |
2655 | 1829 | ||
2656 | return 0; | 1830 | return 0; |
2657 | 1831 | ||
2658 | break; | 1832 | break; |
2659 | 1833 | ||
2660 | case CODEC2_MODE_1600: | 1834 | case CODEC2_MODE_1600: |
2661 | v3 = unpacked_bits[1+1+8+5+1]; | 1835 | v3 = unpacked_bits[1 + 1 + 8 + 5 + 1]; |
2662 | 1836 | ||
2663 | /* if either adjacent frame is voiced, make this one voiced */ | 1837 | /* if either adjacent frame is voiced, make this one voiced */ |
2664 | 1838 | ||
2665 | unpacked_bits[15] = (v1 || v3); | 1839 | unpacked_bits[15] = (v1 || v3); |
2666 | 1840 | ||
2667 | return 0; | 1841 | return 0; |
2668 | 1842 | ||
2669 | break; | 1843 | break; |
2670 | } | 1844 | } |
2671 | 1845 | ||
2672 | return -1; | 1846 | return -1; |
2673 | } | 1847 | } |
2674 | 1848 | ||
2675 | void codec2_set_natural_or_gray(struct CODEC2 *c2, int gray) | 1849 | void codec2_set_natural_or_gray(struct CODEC2 *c2, int gray) { |
2676 | { | 1850 | assert(c2 != NULL); |
2677 | assert(c2 != NULL); | 1851 | c2->gray = gray; |
2678 | c2->gray = gray; | ||
2679 | } | 1852 | } |
2680 | 1853 | ||
2681 | void codec2_set_softdec(struct CODEC2 *c2, float *softdec) | 1854 | void codec2_set_softdec(struct CODEC2 *c2, float *softdec) { |
2682 | { | 1855 | assert(c2 != NULL); |
2683 | assert(c2 != NULL); | 1856 | c2->softdec = softdec; |
2684 | c2->softdec = softdec; | ||
2685 | } | 1857 | } |
2686 | 1858 | ||
2687 | void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *filename) { | 1859 | void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *feat_fn, |
2688 | if ((codec2_state->fmlfeat = fopen(filename, "wb")) == NULL) { | 1860 | char *model_fn) { |
2689 | fprintf(stderr, "error opening machine learning feature file: %s\n", filename); | 1861 | if ((codec2_state->fmlfeat = fopen(feat_fn, "wb")) == NULL) { |
2690 | exit(1); | 1862 | fprintf(stderr, "error opening machine learning feature file: %s\n", |
2691 | } | 1863 | feat_fn); |
1864 | exit(1); | ||
1865 | } | ||
1866 | if (model_fn) { | ||
1867 | if ((codec2_state->fmlmodel = fopen(model_fn, "wb")) == NULL) { | ||
1868 | fprintf(stderr, "error opening machine learning Codec 2 model file: %s\n", | ||
1869 | feat_fn); | ||
1870 | exit(1); | ||
1871 | } | ||
1872 | } | ||
2692 | } | 1873 | } |
2693 | 1874 | ||
2694 | #ifndef __EMBEDDED__ | 1875 | #ifndef __EMBEDDED__ |
2695 | void codec2_load_codebook(struct CODEC2 *codec2_state, int num, char *filename) { | 1876 | void codec2_load_codebook(struct CODEC2 *codec2_state, int num, |
2696 | FILE *f; | 1877 | char *filename) { |
2697 | 1878 | FILE *f; | |
2698 | if ((f = fopen(filename, "rb")) == NULL) { | 1879 | |
2699 | fprintf(stderr, "error opening codebook file: %s\n", filename); | 1880 | if ((f = fopen(filename, "rb")) == NULL) { |
2700 | exit(1); | 1881 | fprintf(stderr, "error opening codebook file: %s\n", filename); |
2701 | } | 1882 | exit(1); |
2702 | //fprintf(stderr, "reading newamp1vq_cb[%d] k=%d m=%d\n", num, newamp1vq_cb[num].k, newamp1vq_cb[num].m); | 1883 | } |
2703 | float tmp[newamp1vq_cb[num].k*newamp1vq_cb[num].m]; | 1884 | // fprintf(stderr, "reading newamp1vq_cb[%d] k=%d m=%d\n", num, |
2704 | int nread = fread(tmp, sizeof(float), newamp1vq_cb[num].k*newamp1vq_cb[num].m, f); | 1885 | // newamp1vq_cb[num].k, newamp1vq_cb[num].m); |
2705 | float *p = (float*)newamp1vq_cb[num].cb; | 1886 | float tmp[newamp1vq_cb[num].k * newamp1vq_cb[num].m]; |
2706 | for(int i=0; i<newamp1vq_cb[num].k*newamp1vq_cb[num].m; i++) | 1887 | int nread = |
2707 | p[i] = tmp[i]; | 1888 | fread(tmp, sizeof(float), newamp1vq_cb[num].k * newamp1vq_cb[num].m, f); |
2708 | // fprintf(stderr, "nread = %d %f %f\n", nread, newamp1vq_cb[num].cb[0], newamp1vq_cb[num].cb[1]); | 1889 | float *p = (float *)newamp1vq_cb[num].cb; |
2709 | assert(nread == newamp1vq_cb[num].k*newamp1vq_cb[num].m); | 1890 | for (int i = 0; i < newamp1vq_cb[num].k * newamp1vq_cb[num].m; i++) |
2710 | fclose(f); | 1891 | p[i] = tmp[i]; |
1892 | // fprintf(stderr, "nread = %d %f %f\n", nread, newamp1vq_cb[num].cb[0], | ||
1893 | // newamp1vq_cb[num].cb[1]); | ||
1894 | assert(nread == newamp1vq_cb[num].k * newamp1vq_cb[num].m); | ||
1895 | fclose(f); | ||
2711 | } | 1896 | } |
2712 | #endif | 1897 | #endif |
2713 | 1898 | ||
2714 | float codec2_get_var(struct CODEC2 *codec2_state) { | 1899 | float codec2_get_var(struct CODEC2 *codec2_state) { |
2715 | if (codec2_state->nse) | 1900 | if (codec2_state->nse) |
2716 | return codec2_state->se/codec2_state->nse; | 1901 | return codec2_state->se / codec2_state->nse; |
2717 | else | 1902 | else |
2718 | return 0; | 1903 | return 0; |
2719 | } | 1904 | } |
2720 | 1905 | ||
2721 | float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K) { | 1906 | float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K) { |
2722 | codec2_state->user_rate_K_vec_no_mean_ = (float*)malloc(sizeof(float)*NEWAMP1_K); | 1907 | codec2_state->user_rate_K_vec_no_mean_ = |
2723 | *K = NEWAMP1_K; | 1908 | (float *)malloc(sizeof(float) * NEWAMP1_K); |
2724 | return codec2_state->user_rate_K_vec_no_mean_; | 1909 | *K = NEWAMP1_K; |
1910 | return codec2_state->user_rate_K_vec_no_mean_; | ||
2725 | } | 1911 | } |
2726 | 1912 | ||
2727 | void codec2_700c_post_filter(struct CODEC2 *codec2_state, int en) { | 1913 | void codec2_700c_post_filter(struct CODEC2 *codec2_state, bool en) { |
2728 | codec2_state->post_filter_en = en; | 1914 | codec2_state->post_filter_en = en; |
2729 | } | 1915 | } |
2730 | 1916 | ||
2731 | void codec2_700c_eq(struct CODEC2 *codec2_state, int en) { | 1917 | void codec2_700c_eq(struct CODEC2 *codec2_state, bool en) { |
2732 | codec2_state->eq_en = en; | 1918 | codec2_state->eq_en = en; |
2733 | codec2_state->se = 0.0; codec2_state->nse = 0; | 1919 | codec2_state->se = 0.0; |
1920 | codec2_state->nse = 0; | ||
2734 | } | 1921 | } |
@@ -26,26 +26,22 @@ | |||
26 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 26 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #ifndef __CODEC2__ | ||
30 | #define __CODEC2__ | ||
31 | #include "version.h" | ||
32 | #include <stdbool.h> | ||
33 | |||
29 | #ifdef __cplusplus | 34 | #ifdef __cplusplus |
30 | extern "C" { | 35 | extern "C" { |
31 | #endif | 36 | #endif |
32 | 37 | ||
33 | #ifndef __CODEC2__ | 38 | #define CODEC2_MODE_3200 0 |
34 | #define __CODEC2__ | 39 | #define CODEC2_MODE_2400 1 |
35 | 40 | #define CODEC2_MODE_1600 2 | |
36 | #include <version.h> | 41 | #define CODEC2_MODE_1400 3 |
37 | 42 | #define CODEC2_MODE_1300 4 | |
38 | #define CODEC2_MODE_3200 0 | 43 | #define CODEC2_MODE_1200 5 |
39 | #define CODEC2_MODE_2400 1 | 44 | #define CODEC2_MODE_700C 8 |
40 | #define CODEC2_MODE_1600 2 | ||
41 | #define CODEC2_MODE_1400 3 | ||
42 | #define CODEC2_MODE_1300 4 | ||
43 | #define CODEC2_MODE_1200 5 | ||
44 | #define CODEC2_MODE_700 6 | ||
45 | #define CODEC2_MODE_700B 7 | ||
46 | #define CODEC2_MODE_700C 8 | ||
47 | #define CODEC2_MODE_450 10 | ||
48 | #define CODEC2_MODE_450PWB 11 | ||
49 | 45 | ||
50 | #ifndef CODEC2_MODE_EN_DEFAULT | 46 | #ifndef CODEC2_MODE_EN_DEFAULT |
51 | #define CODEC2_MODE_EN_DEFAULT 1 | 47 | #define CODEC2_MODE_EN_DEFAULT 1 |
@@ -55,76 +51,70 @@ | |||
55 | // disable during compile time with -DCODEC2_MODE_1600_EN=0 | 51 | // disable during compile time with -DCODEC2_MODE_1600_EN=0 |
56 | // all but CODEC2 1600 are enabled then | 52 | // all but CODEC2 1600 are enabled then |
57 | 53 | ||
58 | //or the other way round | 54 | // or the other way round |
59 | // -DCODEC2_MODE_EN_DEFAULT=0 -DCODEC2_MODE_1600_EN=1 | 55 | // -DCODEC2_MODE_EN_DEFAULT=0 -DCODEC2_MODE_1600_EN=1 |
60 | // only CODEC2 Mode 1600 | 56 | // only CODEC2 Mode 1600 |
61 | 57 | ||
62 | #if !defined(CODEC2_MODE_3200_EN) | 58 | #if !defined(CODEC2_MODE_3200_EN) |
63 | #define CODEC2_MODE_3200_EN CODEC2_MODE_EN_DEFAULT | 59 | #define CODEC2_MODE_3200_EN CODEC2_MODE_EN_DEFAULT |
64 | #endif | 60 | #endif |
65 | #if !defined(CODEC2_MODE_2400_EN) | 61 | #if !defined(CODEC2_MODE_2400_EN) |
66 | #define CODEC2_MODE_2400_EN CODEC2_MODE_EN_DEFAULT | 62 | #define CODEC2_MODE_2400_EN CODEC2_MODE_EN_DEFAULT |
67 | #endif | 63 | #endif |
68 | #if !defined(CODEC2_MODE_1600_EN) | 64 | #if !defined(CODEC2_MODE_1600_EN) |
69 | #define CODEC2_MODE_1600_EN CODEC2_MODE_EN_DEFAULT | 65 | #define CODEC2_MODE_1600_EN CODEC2_MODE_EN_DEFAULT |
70 | #endif | 66 | #endif |
71 | #if !defined(CODEC2_MODE_1400_EN) | 67 | #if !defined(CODEC2_MODE_1400_EN) |
72 | #define CODEC2_MODE_1400_EN CODEC2_MODE_EN_DEFAULT | 68 | #define CODEC2_MODE_1400_EN CODEC2_MODE_EN_DEFAULT |
73 | #endif | 69 | #endif |
74 | #if !defined(CODEC2_MODE_1300_EN) | 70 | #if !defined(CODEC2_MODE_1300_EN) |
75 | #define CODEC2_MODE_1300_EN CODEC2_MODE_EN_DEFAULT | 71 | #define CODEC2_MODE_1300_EN CODEC2_MODE_EN_DEFAULT |
76 | #endif | 72 | #endif |
77 | #if !defined(CODEC2_MODE_1200_EN) | 73 | #if !defined(CODEC2_MODE_1200_EN) |
78 | #define CODEC2_MODE_1200_EN CODEC2_MODE_EN_DEFAULT | 74 | #define CODEC2_MODE_1200_EN CODEC2_MODE_EN_DEFAULT |
79 | #endif | ||
80 | #if !defined(CODEC2_MODE_700_EN) | ||
81 | #define CODEC2_MODE_700_EN CODEC2_MODE_EN_DEFAULT | ||
82 | #endif | ||
83 | #if !defined(CODEC2_MODE_700B_EN) | ||
84 | #define CODEC2_MODE_700B_EN CODEC2_MODE_EN_DEFAULT | ||
85 | #endif | 75 | #endif |
86 | #if !defined(CODEC2_MODE_700C_EN) | 76 | #if !defined(CODEC2_MODE_700C_EN) |
87 | #define CODEC2_MODE_700C_EN CODEC2_MODE_EN_DEFAULT | 77 | #define CODEC2_MODE_700C_EN CODEC2_MODE_EN_DEFAULT |
88 | #endif | ||
89 | #if !defined(CODEC2_MODE_450_EN) | ||
90 | #define CODEC2_MODE_450_EN CODEC2_MODE_EN_DEFAULT | ||
91 | #endif | ||
92 | #if !defined(CODEC2_MODE_450PWB_EN) | ||
93 | #define CODEC2_MODE_450PWB_EN CODEC2_MODE_EN_DEFAULT | ||
94 | #endif | 78 | #endif |
95 | 79 | ||
96 | #define CODEC2_MODE_ACTIVE(mode_name, var) ((mode_name##_EN) == 0 ? 0: (var) == mode_name) | 80 | #define CODEC2_MODE_ACTIVE(mode_name, var) \ |
81 | ((mode_name##_EN) == 0 ? 0 : (var) == mode_name) | ||
97 | 82 | ||
98 | struct CODEC2; | 83 | struct CODEC2; |
99 | 84 | ||
100 | struct CODEC2 * codec2_create(int mode); | 85 | struct CODEC2 *codec2_create(int mode); |
101 | void codec2_destroy(struct CODEC2 *codec2_state); | 86 | void codec2_destroy(struct CODEC2 *codec2_state); |
102 | void codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]); | 87 | void codec2_encode(struct CODEC2 *codec2_state, unsigned char bytes[], |
103 | void codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits); | 88 | short speech_in[]); |
104 | void codec2_decode_ber(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits, float ber_est); | 89 | void codec2_decode(struct CODEC2 *codec2_state, short speech_out[], |
105 | int codec2_samples_per_frame(struct CODEC2 *codec2_state); | 90 | const unsigned char bytes[]); |
106 | int codec2_bits_per_frame(struct CODEC2 *codec2_state); | 91 | void codec2_decode_ber(struct CODEC2 *codec2_state, short speech_out[], |
107 | 92 | const unsigned char *bytes, float ber_est); | |
108 | void codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma); | 93 | int codec2_samples_per_frame(struct CODEC2 *codec2_state); |
109 | int codec2_get_spare_bit_index(struct CODEC2 *codec2_state); | 94 | int codec2_bits_per_frame(struct CODEC2 *codec2_state); |
110 | int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]); | 95 | int codec2_bytes_per_frame(struct CODEC2 *codec2_state); |
96 | |||
97 | void codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, | ||
98 | int bass_boost, float beta, float gamma); | ||
99 | int codec2_get_spare_bit_index(struct CODEC2 *codec2_state); | ||
100 | int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, char unpacked_bits[]); | ||
111 | void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); | 101 | void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); |
112 | void codec2_set_softdec(struct CODEC2 *c2, float *softdec); | 102 | void codec2_set_softdec(struct CODEC2 *c2, float *softdec); |
113 | float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); | 103 | float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); |
114 | 104 | ||
115 | // support for ML and VQ experiments | 105 | // support for ML and VQ experiments |
116 | void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *filename); | 106 | void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *feat_filename, |
107 | char *model_filename); | ||
117 | void codec2_load_codebook(struct CODEC2 *codec2_state, int num, char *filename); | 108 | void codec2_load_codebook(struct CODEC2 *codec2_state, int num, char *filename); |
118 | float codec2_get_var(struct CODEC2 *codec2_state); | 109 | float codec2_get_var(struct CODEC2 *codec2_state); |
119 | float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K); | 110 | float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K); |
120 | 111 | ||
121 | // 700C post filter and equaliser | 112 | // 700C post filter and equaliser |
122 | void codec2_700c_post_filter(struct CODEC2 *codec2_state, int en); | 113 | void codec2_700c_post_filter(struct CODEC2 *codec2_state, bool en); |
123 | void codec2_700c_eq(struct CODEC2 *codec2_state, int en); | 114 | void codec2_700c_eq(struct CODEC2 *codec2_state, bool en); |
124 | |||
125 | #endif | ||
126 | 115 | ||
127 | #ifdef __cplusplus | 116 | #ifdef __cplusplus |
128 | } | 117 | } |
129 | #endif | 118 | #endif |
130 | 119 | ||
120 | #endif | ||
diff --git a/codec2_fft.c b/codec2_fft.c index 14b8670..7a75062 100644 --- a/codec2_fft.c +++ b/codec2_fft.c | |||
@@ -61,66 +61,63 @@ static const arm_cfft_instance_f32* arm_fft_cache_get(const arm_cfft_instance_f3 | |||
61 | #endif | 61 | #endif |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | void codec2_fft_free(codec2_fft_cfg cfg) | 64 | void codec2_fft_free(codec2_fft_cfg cfg) { |
65 | { | ||
66 | #ifdef USE_KISS_FFT | 65 | #ifdef USE_KISS_FFT |
67 | KISS_FFT_FREE(cfg); | 66 | KISS_FFT_FREE(cfg); |
68 | #else | 67 | #else |
69 | FREE(cfg); | 68 | FREE(cfg); |
70 | #endif | 69 | #endif |
71 | } | 70 | } |
72 | 71 | ||
73 | codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem) | 72 | codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, |
74 | { | 73 | size_t* lenmem) { |
75 | codec2_fft_cfg retval; | 74 | codec2_fft_cfg retval; |
76 | #ifdef USE_KISS_FFT | 75 | #ifdef USE_KISS_FFT |
77 | retval = kiss_fft_alloc(nfft, inverse_fft, mem, lenmem); | 76 | retval = kiss_fft_alloc(nfft, inverse_fft, mem, lenmem); |
78 | #else | 77 | #else |
79 | retval = MALLOC(sizeof(codec2_fft_struct)); | 78 | retval = MALLOC(sizeof(codec2_fft_struct)); |
80 | retval->inverse = inverse_fft; | 79 | retval->inverse = inverse_fft; |
81 | switch(nfft) | 80 | switch (nfft) { |
82 | { | ||
83 | case 128: | 81 | case 128: |
84 | retval->instance = &arm_cfft_sR_f32_len128; | 82 | retval->instance = &arm_cfft_sR_f32_len128; |
85 | break; | 83 | break; |
86 | case 256: | 84 | case 256: |
87 | retval->instance = &arm_cfft_sR_f32_len256; | 85 | retval->instance = &arm_cfft_sR_f32_len256; |
88 | break; | 86 | break; |
89 | case 512: | 87 | case 512: |
90 | retval->instance = &arm_cfft_sR_f32_len512; | 88 | retval->instance = &arm_cfft_sR_f32_len512; |
91 | break; | 89 | break; |
92 | // case 1024: | 90 | // case 1024: |
93 | // retval->instance = &arm_cfft_sR_f32_len1024; | 91 | // retval->instance = &arm_cfft_sR_f32_len1024; |
94 | // break; | 92 | // break; |
95 | default: | 93 | default: |
96 | abort(); | 94 | abort(); |
97 | } | 95 | } |
98 | // retval->instance = arm_fft_cache_get(retval->instance); | 96 | // retval->instance = arm_fft_cache_get(retval->instance); |
99 | #endif | 97 | #endif |
100 | return retval; | 98 | return retval; |
101 | } | 99 | } |
102 | 100 | ||
103 | codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem) | 101 | codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, |
104 | { | 102 | size_t* lenmem) { |
105 | codec2_fftr_cfg retval; | 103 | codec2_fftr_cfg retval; |
106 | #ifdef USE_KISS_FFT | 104 | #ifdef USE_KISS_FFT |
107 | retval = kiss_fftr_alloc(nfft, inverse_fft, mem, lenmem); | 105 | retval = kiss_fftr_alloc(nfft, inverse_fft, mem, lenmem); |
108 | #else | 106 | #else |
109 | retval = MALLOC(sizeof(codec2_fftr_struct)); | 107 | retval = MALLOC(sizeof(codec2_fftr_struct)); |
110 | retval->inverse = inverse_fft; | 108 | retval->inverse = inverse_fft; |
111 | retval->instance = MALLOC(sizeof(arm_rfft_fast_instance_f32)); | 109 | retval->instance = MALLOC(sizeof(arm_rfft_fast_instance_f32)); |
112 | arm_rfft_fast_init_f32(retval->instance,nfft); | 110 | arm_rfft_fast_init_f32(retval->instance, nfft); |
113 | // memcpy(&retval->instance->Sint,arm_fft_cache_get(&retval->instance->Sint),sizeof(arm_cfft_instance_f32)); | 111 | // memcpy(&retval->instance->Sint,arm_fft_cache_get(&retval->instance->Sint),sizeof(arm_cfft_instance_f32)); |
114 | #endif | 112 | #endif |
115 | return retval; | 113 | return retval; |
116 | } | 114 | } |
117 | void codec2_fftr_free(codec2_fftr_cfg cfg) | 115 | void codec2_fftr_free(codec2_fftr_cfg cfg) { |
118 | { | ||
119 | #ifdef USE_KISS_FFT | 116 | #ifdef USE_KISS_FFT |
120 | KISS_FFT_FREE(cfg); | 117 | KISS_FFT_FREE(cfg); |
121 | #else | 118 | #else |
122 | FREE(cfg->instance); | 119 | FREE(cfg->instance); |
123 | FREE(cfg); | 120 | FREE(cfg); |
124 | #endif | 121 | #endif |
125 | } | 122 | } |
126 | 123 | ||
@@ -129,30 +126,25 @@ void codec2_fftr_free(codec2_fftr_cfg cfg) | |||
129 | // not noticeable | 126 | // not noticeable |
130 | // the reduced usage of RAM and increased performance on STM32 platforms | 127 | // the reduced usage of RAM and increased performance on STM32 platforms |
131 | // should be worth it. | 128 | // should be worth it. |
132 | void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout) | 129 | void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout) { |
133 | { | ||
134 | |||
135 | #ifdef USE_KISS_FFT | 130 | #ifdef USE_KISS_FFT |
131 | // decide whether to use the local stack based buffer for in | ||
132 | // or to allow kiss_fft to allocate RAM | ||
133 | // second part is just to play safe since first method | ||
134 | // is much faster and uses less RAM | ||
135 | if (cfg->nfft <= 512) { | ||
136 | kiss_fft_cpx in[512]; | 136 | kiss_fft_cpx in[512]; |
137 | // decide whether to use the local stack based buffer for in | 137 | memcpy(in, inout, cfg->nfft * sizeof(kiss_fft_cpx)); |
138 | // or to allow kiss_fft to allocate RAM | 138 | kiss_fft(cfg, in, (kiss_fft_cpx*)inout); |
139 | // second part is just to play safe since first method | 139 | } else { |
140 | // is much faster and uses less RAM | 140 | kiss_fft(cfg, (kiss_fft_cpx*)inout, (kiss_fft_cpx*)inout); |
141 | if (cfg->nfft <= 512) | 141 | } |
142 | { | ||
143 | memcpy(in,inout,cfg->nfft*sizeof(kiss_fft_cpx)); | ||
144 | kiss_fft(cfg, in, (kiss_fft_cpx*)inout); | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | kiss_fft(cfg, (kiss_fft_cpx*)inout, (kiss_fft_cpx*)inout); | ||
149 | } | ||
150 | #else | 142 | #else |
151 | arm_cfft_f32(cfg->instance,(float*)inout,cfg->inverse,1); | 143 | arm_cfft_f32(cfg->instance, (float*)inout, cfg->inverse, 1); |
152 | if (cfg->inverse) | 144 | if (cfg->inverse) { |
153 | { | 145 | arm_scale_f32((float*)inout, cfg->instance->fftLen, (float*)inout, |
154 | arm_scale_f32((float*)inout,cfg->instance->fftLen,(float*)inout,cfg->instance->fftLen*2); | 146 | cfg->instance->fftLen * 2); |
155 | } | 147 | } |
156 | 148 | ||
157 | #endif | 149 | #endif |
158 | } | 150 | } |
diff --git a/codec2_fft.h b/codec2_fft.h index c741202..1952864 100644 --- a/codec2_fft.h +++ b/codec2_fft.h | |||
@@ -9,96 +9,91 @@ | |||
9 | #define DRIVERS_FREEDV_CODEC2_FFT_H_ | 9 | #define DRIVERS_FREEDV_CODEC2_FFT_H_ |
10 | 10 | ||
11 | #include <assert.h> | 11 | #include <assert.h> |
12 | #include <stdlib.h> | 12 | #include <math.h> |
13 | #include <stdio.h> | 13 | #include <stdio.h> |
14 | #include <stdlib.h> | ||
14 | #include <string.h> | 15 | #include <string.h> |
15 | #include <math.h> | ||
16 | 16 | ||
17 | #ifdef FDV_ARM_MATH | 17 | #ifndef FDV_ARM_MATH |
18 | #include "fdv_arm_math.h" | 18 | #define USE_KISS_FFT |
19 | #else | 19 | #else |
20 | #define USE_KISS_FFT | 20 | #include "arm_const_structs.h" |
21 | #include "arm_math.h" | ||
21 | #endif | 22 | #endif |
22 | 23 | ||
23 | #include "defines.h" | ||
24 | #include "comp.h" | 24 | #include "comp.h" |
25 | #include "defines.h" | ||
25 | 26 | ||
26 | 27 | typedef COMP codec2_fft_cpx; | |
27 | typedef COMP codec2_fft_cpx; | ||
28 | #include "kiss_fftr.h" | 28 | #include "kiss_fftr.h" |
29 | 29 | ||
30 | #ifdef USE_KISS_FFT | 30 | #ifdef USE_KISS_FFT |
31 | #include "kiss_fft.h" | 31 | #include "kiss_fft.h" |
32 | typedef kiss_fftr_cfg codec2_fftr_cfg; | 32 | typedef kiss_fftr_cfg codec2_fftr_cfg; |
33 | typedef kiss_fft_cfg codec2_fft_cfg; | 33 | typedef kiss_fft_cfg codec2_fft_cfg; |
34 | typedef kiss_fft_scalar codec2_fft_scalar; | 34 | typedef kiss_fft_scalar codec2_fft_scalar; |
35 | #else | 35 | #else |
36 | typedef float32_t codec2_fft_scalar; | 36 | typedef float32_t codec2_fft_scalar; |
37 | typedef struct { | 37 | typedef struct { |
38 | arm_rfft_fast_instance_f32* instance; | 38 | arm_rfft_fast_instance_f32* instance; |
39 | int inverse; | 39 | int inverse; |
40 | } codec2_fftr_struct; | 40 | } codec2_fftr_struct; |
41 | 41 | ||
42 | typedef codec2_fftr_struct* codec2_fftr_cfg; | 42 | typedef codec2_fftr_struct* codec2_fftr_cfg; |
43 | 43 | ||
44 | typedef struct { | 44 | typedef struct { |
45 | const arm_cfft_instance_f32* instance; | 45 | const arm_cfft_instance_f32* instance; |
46 | int inverse; | 46 | int inverse; |
47 | } codec2_fft_struct; | 47 | } codec2_fft_struct; |
48 | typedef codec2_fft_struct* codec2_fft_cfg; | 48 | typedef codec2_fft_struct* codec2_fft_cfg; |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | 51 | static inline void codec2_fftr(codec2_fftr_cfg cfg, codec2_fft_scalar* in, | |
52 | 52 | codec2_fft_cpx* out) { | |
53 | static inline void codec2_fftr(codec2_fftr_cfg cfg, codec2_fft_scalar* in, codec2_fft_cpx* out) | ||
54 | { | ||
55 | |||
56 | #ifdef USE_KISS_FFT | 53 | #ifdef USE_KISS_FFT |
57 | kiss_fftr(cfg, in, (kiss_fft_cpx*)out); | 54 | kiss_fftr(cfg, in, (kiss_fft_cpx*)out); |
58 | #else | 55 | #else |
59 | arm_rfft_fast_f32(cfg->instance,in,(float*)out,cfg->inverse); | 56 | arm_rfft_fast_f32(cfg->instance, in, (float*)out, cfg->inverse); |
60 | out->imag = 0; // remove out[FFT_ENC/2]->real stored in out[0].imag | 57 | out->imag = 0; // remove out[FFT_ENC/2]->real stored in out[0].imag |
61 | #endif | 58 | #endif |
62 | } | 59 | } |
63 | 60 | ||
64 | static inline void codec2_fftri(codec2_fftr_cfg cfg, codec2_fft_cpx* in, codec2_fft_scalar* out) | 61 | static inline void codec2_fftri(codec2_fftr_cfg cfg, codec2_fft_cpx* in, |
65 | { | 62 | codec2_fft_scalar* out) { |
66 | #ifdef USE_KISS_FFT | 63 | #ifdef USE_KISS_FFT |
67 | kiss_fftri(cfg, (kiss_fft_cpx*)in, out); | 64 | kiss_fftri(cfg, (kiss_fft_cpx*)in, out); |
68 | #else | 65 | #else |
69 | arm_rfft_fast_f32(cfg->instance,(float*)in,out,cfg->inverse); | 66 | arm_rfft_fast_f32(cfg->instance, (float*)in, out, cfg->inverse); |
70 | // arm_scale_f32(out,cfg->instance->fftLenRFFT,out,cfg->instance->fftLenRFFT); | 67 | // arm_scale_f32(out,cfg->instance->fftLenRFFT,out,cfg->instance->fftLenRFFT); |
71 | #endif | 68 | #endif |
72 | |||
73 | } | 69 | } |
74 | 70 | ||
75 | codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem); | 71 | codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, |
76 | codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem); | 72 | size_t* lenmem); |
73 | codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, | ||
74 | size_t* lenmem); | ||
77 | void codec2_fft_free(codec2_fft_cfg cfg); | 75 | void codec2_fft_free(codec2_fft_cfg cfg); |
78 | void codec2_fftr_free(codec2_fftr_cfg cfg); | 76 | void codec2_fftr_free(codec2_fftr_cfg cfg); |
79 | 77 | ||
80 | 78 | static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, | |
81 | static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, codec2_fft_cpx* out) | 79 | codec2_fft_cpx* out) { |
82 | { | ||
83 | |||
84 | #ifdef USE_KISS_FFT | 80 | #ifdef USE_KISS_FFT |
85 | kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out); | 81 | kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out); |
86 | #else | 82 | #else |
87 | memcpy(out,in,cfg->instance->fftLen*2*sizeof(float)); | 83 | memcpy(out, in, cfg->instance->fftLen * 2 * sizeof(float)); |
88 | arm_cfft_f32(cfg->instance,(float*)out,cfg->inverse, 1); | 84 | arm_cfft_f32(cfg->instance, (float*)out, cfg->inverse, 1); |
89 | // TODO: this is not nice, but for now required to keep changes minimal | 85 | // TODO: this is not nice, but for now required to keep changes minimal |
90 | // however, since main goal is to reduce the memory usage | 86 | // however, since main goal is to reduce the memory usage |
91 | // we should convert to an in place interface | 87 | // we should convert to an in place interface |
92 | // on PC like platforms the overhead of using the "inplace" kiss_fft calls | 88 | // on PC like platforms the overhead of using the "inplace" kiss_fft calls |
93 | // is neglectable compared to the gain in memory usage on STM32 platforms | 89 | // is neglectable compared to the gain in memory usage on STM32 platforms |
94 | if (cfg->inverse) | 90 | if (cfg->inverse) { |
95 | { | 91 | arm_scale_f32((float*)out, cfg->instance->fftLen, (float*)out, |
96 | arm_scale_f32((float*)out,cfg->instance->fftLen,(float*)out,cfg->instance->fftLen*2); | 92 | cfg->instance->fftLen * 2); |
97 | } | 93 | } |
98 | #endif | 94 | #endif |
99 | } | 95 | } |
100 | 96 | ||
101 | void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout); | 97 | void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout); |
102 | 98 | ||
103 | |||
104 | #endif | 99 | #endif |
diff --git a/codec2_internal.h b/codec2_internal.h index b46e358..32cd7eb 100644 --- a/codec2_internal.h +++ b/codec2_internal.h | |||
@@ -28,81 +28,76 @@ | |||
28 | 28 | ||
29 | #ifndef __CODEC2_INTERNAL__ | 29 | #ifndef __CODEC2_INTERNAL__ |
30 | #define __CODEC2_INTERNAL__ | 30 | #define __CODEC2_INTERNAL__ |
31 | #include <stdbool.h> | ||
31 | 32 | ||
32 | #include "codec2_fft.h" | 33 | #include "codec2_fft.h" |
33 | #include "newamp1.h" | 34 | #include "newamp1.h" |
34 | #include "newamp2.h" | ||
35 | 35 | ||
36 | struct CODEC2 { | 36 | struct CODEC2 { |
37 | int mode; | 37 | int mode; |
38 | C2CONST c2const; | 38 | C2CONST c2const; |
39 | int Fs; | 39 | int Fs; |
40 | int n_samp; | 40 | int n_samp; |
41 | int m_pitch; | 41 | int m_pitch; |
42 | codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */ | 42 | codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */ |
43 | codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ | 43 | codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ |
44 | float *w; /* [m_pitch] time domain hamming window */ | 44 | float *w; /* [m_pitch] time domain hamming window */ |
45 | float W[FFT_ENC]; /* DFT of w[] */ | 45 | float W[FFT_ENC]; /* DFT of w[] */ |
46 | float *Pn; /* [2*n_samp] trapezoidal synthesis window */ | 46 | float *Pn; /* [2*n_samp] trapezoidal synthesis window */ |
47 | float *bpf_buf; /* buffer for band pass filter */ | 47 | float *bpf_buf; /* buffer for band pass filter */ |
48 | float *Sn; /* [m_pitch] input speech */ | 48 | float *Sn; /* [m_pitch] input speech */ |
49 | float hpf_states[2]; /* high pass filter states */ | 49 | float hpf_states[2]; /* high pass filter states */ |
50 | void *nlp; /* pitch predictor states */ | 50 | void *nlp; /* pitch predictor states */ |
51 | int gray; /* non-zero for gray encoding */ | 51 | int gray; /* non-zero for gray encoding */ |
52 | 52 | ||
53 | codec2_fftr_cfg fftr_inv_cfg; /* inverse FFT config */ | 53 | codec2_fftr_cfg fftr_inv_cfg; /* inverse FFT config */ |
54 | float *Sn_; /* [2*n_samp] synthesised output speech */ | 54 | float *Sn_; /* [2*n_samp] synthesised output speech */ |
55 | float ex_phase; /* excitation model phase track */ | 55 | float ex_phase; /* excitation model phase track */ |
56 | float bg_est; /* background noise estimate for post filter */ | 56 | float bg_est; /* background noise estimate for post filter */ |
57 | float prev_f0_enc; /* previous frame's f0 estimate */ | 57 | float prev_f0_enc; /* previous frame's f0 estimate */ |
58 | MODEL prev_model_dec; /* previous frame's model parameters */ | 58 | MODEL prev_model_dec; /* previous frame's model parameters */ |
59 | float prev_lsps_dec[LPC_ORD]; /* previous frame's LSPs */ | 59 | float prev_lsps_dec[LPC_ORD]; /* previous frame's LSPs */ |
60 | float prev_e_dec; /* previous frame's LPC energy */ | 60 | float prev_e_dec; /* previous frame's LPC energy */ |
61 | 61 | ||
62 | int lpc_pf; /* LPC post filter on */ | 62 | int lpc_pf; /* LPC post filter on */ |
63 | int bass_boost; /* LPC post filter bass boost */ | 63 | int bass_boost; /* LPC post filter bass boost */ |
64 | float beta; /* LPC post filter parameters */ | 64 | float beta; /* LPC post filter parameters */ |
65 | float gamma; | 65 | float gamma; |
66 | 66 | ||
67 | float xq_enc[2]; /* joint pitch and energy VQ states */ | 67 | float xq_enc[2]; /* joint pitch and energy VQ states */ |
68 | float xq_dec[2]; | 68 | float xq_dec[2]; |
69 | 69 | ||
70 | int smoothing; /* enable smoothing for channels with errors */ | 70 | int smoothing; /* enable smoothing for channels with errors */ |
71 | float *softdec; /* optional soft decn bits from demod */ | 71 | float *softdec; /* optional soft decn bits from demod */ |
72 | 72 | ||
73 | /* newamp1 states */ | 73 | /* newamp1 states */ |
74 | 74 | ||
75 | float rate_K_sample_freqs_kHz[NEWAMP1_K]; | 75 | float rate_K_sample_freqs_kHz[NEWAMP1_K]; |
76 | float prev_rate_K_vec_[NEWAMP1_K]; | 76 | float prev_rate_K_vec_[NEWAMP1_K]; |
77 | float Wo_left; | 77 | float Wo_left; |
78 | int voicing_left; | 78 | int voicing_left; |
79 | codec2_fft_cfg phase_fft_fwd_cfg; | 79 | codec2_fft_cfg phase_fft_fwd_cfg; |
80 | codec2_fft_cfg phase_fft_inv_cfg; | 80 | codec2_fft_cfg phase_fft_inv_cfg; |
81 | float se; /* running sum of squared error */ | 81 | float se; /* running sum of squared error */ |
82 | unsigned int nse; /* number of terms in sum */ | 82 | unsigned int nse; /* number of terms in sum */ |
83 | float *user_rate_K_vec_no_mean_; /* optional, user supplied vector for quantisation experiments */ | 83 | float *user_rate_K_vec_no_mean_; /* optional, user supplied vector for |
84 | int post_filter_en; | 84 | quantisation experiments */ |
85 | float eq[NEWAMP1_K]; /* optional equaliser */ | 85 | bool post_filter_en; |
86 | int eq_en; | 86 | float eq[NEWAMP1_K]; /* optional equaliser */ |
87 | 87 | bool eq_en; | |
88 | /*newamp2 states (also uses newamp1 states )*/ | 88 | |
89 | float energy_prev; | 89 | /* used to dump features for deep learning experiments */ |
90 | float n2_rate_K_sample_freqs_kHz[NEWAMP2_K]; | 90 | FILE *fmlfeat, *fmlmodel; |
91 | float n2_prev_rate_K_vec_[NEWAMP2_K]; | 91 | |
92 | float n2_pwb_rate_K_sample_freqs_kHz[NEWAMP2_16K_K]; | 92 | /* encode/decode function pointers for the selected mode */ |
93 | float n2_pwb_prev_rate_K_vec_[NEWAMP2_16K_K]; | 93 | void (*encode)(struct CODEC2 *c2, unsigned char *bits, short speech[]); |
94 | 94 | void (*decode)(struct CODEC2 *c2, short speech[], const unsigned char *bits); | |
95 | /* used to dump features for deep learning experiments */ | 95 | void (*decode_ber)(struct CODEC2 *c2, short speech[], |
96 | FILE *fmlfeat; | 96 | const unsigned char *bits, float ber_est); |
97 | |||
98 | /* encode/decode function pointers for the selected mode */ | ||
99 | void (*encode)(struct CODEC2 *c2, unsigned char * bits, short speech[]); | ||
100 | void (*decode)(struct CODEC2 *c2, short speech[], const unsigned char * bits); | ||
101 | void (*decode_ber)(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est); | ||
102 | }; | 97 | }; |
103 | 98 | ||
104 | // test and debug | 99 | // test and debug |
105 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); | 100 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); |
106 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, | 101 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, |
107 | COMP Aw[], float gain); | 102 | COMP Aw[], float gain); |
108 | #endif | 103 | #endif |
diff --git a/comp_prim.h b/comp_prim.h index d0f070a..e0166d3 100644 --- a/comp_prim.h +++ b/comp_prim.h | |||
@@ -28,114 +28,111 @@ | |||
28 | #ifndef __COMP_PRIM__ | 28 | #ifndef __COMP_PRIM__ |
29 | #define __COMP_PRIM__ | 29 | #define __COMP_PRIM__ |
30 | 30 | ||
31 | #include <math.h> | ||
32 | |||
31 | /*---------------------------------------------------------------------------*\ | 33 | /*---------------------------------------------------------------------------*\ |
32 | 34 | ||
33 | FUNCTIONS | 35 | FUNCTIONS |
34 | 36 | ||
35 | \*---------------------------------------------------------------------------*/ | 37 | \*---------------------------------------------------------------------------*/ |
36 | 38 | ||
37 | inline static COMP cneg(COMP a) | 39 | inline static COMP cneg(COMP a) { |
38 | { | 40 | COMP res; |
39 | COMP res; | ||
40 | 41 | ||
41 | res.real = -a.real; | 42 | res.real = -a.real; |
42 | res.imag = -a.imag; | 43 | res.imag = -a.imag; |
43 | 44 | ||
44 | return res; | 45 | return res; |
45 | } | 46 | } |
46 | 47 | ||
47 | inline static COMP cconj(COMP a) | 48 | inline static COMP cconj(COMP a) { |
48 | { | 49 | COMP res; |
49 | COMP res; | ||
50 | 50 | ||
51 | res.real = a.real; | 51 | res.real = a.real; |
52 | res.imag = -a.imag; | 52 | res.imag = -a.imag; |
53 | 53 | ||
54 | return res; | 54 | return res; |
55 | } | 55 | } |
56 | 56 | ||
57 | inline static COMP cmult(COMP a, COMP b) | 57 | inline static COMP cmult(COMP a, COMP b) { |
58 | { | 58 | COMP res; |
59 | COMP res; | ||
60 | 59 | ||
61 | res.real = a.real*b.real - a.imag*b.imag; | 60 | res.real = a.real * b.real - a.imag * b.imag; |
62 | res.imag = a.real*b.imag + a.imag*b.real; | 61 | res.imag = a.real * b.imag + a.imag * b.real; |
63 | 62 | ||
64 | return res; | 63 | return res; |
65 | } | 64 | } |
66 | 65 | ||
67 | inline static COMP fcmult(float a, COMP b) | 66 | inline static COMP fcmult(float a, COMP b) { |
68 | { | 67 | COMP res; |
69 | COMP res; | ||
70 | 68 | ||
71 | res.real = a*b.real; | 69 | res.real = a * b.real; |
72 | res.imag = a*b.imag; | 70 | res.imag = a * b.imag; |
73 | 71 | ||
74 | return res; | 72 | return res; |
75 | } | 73 | } |
76 | 74 | ||
77 | inline static COMP cadd(COMP a, COMP b) | 75 | inline static COMP cadd(COMP a, COMP b) { |
78 | { | 76 | COMP res; |
79 | COMP res; | ||
80 | 77 | ||
81 | res.real = a.real + b.real; | 78 | res.real = a.real + b.real; |
82 | res.imag = a.imag + b.imag; | 79 | res.imag = a.imag + b.imag; |
83 | 80 | ||
84 | return res; | 81 | return res; |
85 | } | 82 | } |
86 | 83 | ||
87 | inline static float cabsolute(COMP a) | 84 | inline static float cabsolute(COMP a) { |
88 | { | 85 | return sqrtf((a.real * a.real) + (a.imag * a.imag)); |
89 | return sqrtf((a.real * a.real) + (a.imag * a.imag) ); | ||
90 | } | 86 | } |
91 | 87 | ||
92 | /* | 88 | /* |
93 | * Euler's formula in a new convenient function | 89 | * Euler's formula in a new convenient function |
94 | */ | 90 | */ |
95 | inline static COMP comp_exp_j(float phi){ | 91 | inline static COMP comp_exp_j(float phi) { |
96 | COMP res; | 92 | COMP res; |
97 | res.real = cosf(phi); | 93 | res.real = cosf(phi); |
98 | res.imag = sinf(phi); | 94 | res.imag = sinf(phi); |
99 | return res; | 95 | return res; |
100 | } | 96 | } |
101 | 97 | ||
102 | /* | 98 | /* |
103 | * Quick and easy complex 0 | 99 | * Quick and easy complex 0 |
104 | */ | 100 | */ |
105 | inline static COMP comp0(){ | 101 | inline static COMP comp0() { |
106 | COMP res; | 102 | COMP res; |
107 | res.real = 0; | 103 | res.real = 0; |
108 | res.imag = 0; | 104 | res.imag = 0; |
109 | return res; | 105 | return res; |
110 | } | 106 | } |
111 | 107 | ||
112 | /* | 108 | /* |
113 | * Quick and easy complex subtract | 109 | * Quick and easy complex subtract |
114 | */ | 110 | */ |
115 | inline static COMP csub(COMP a, COMP b){ | 111 | inline static COMP csub(COMP a, COMP b) { |
116 | COMP res; | 112 | COMP res; |
117 | res.real = a.real-b.real; | 113 | res.real = a.real - b.real; |
118 | res.imag = a.imag-b.imag; | 114 | res.imag = a.imag - b.imag; |
119 | return res; | 115 | return res; |
120 | } | 116 | } |
121 | 117 | ||
122 | /* | 118 | /* |
123 | * Compare the magnitude of a and b. if |a|>|b|, return true, otw false. | 119 | * Compare the magnitude of a and b. if |a|>|b|, return true, otw false. |
124 | * This needs no square roots | 120 | * This needs no square roots |
125 | */ | 121 | */ |
126 | inline static int comp_mag_gt(COMP a,COMP b){ | 122 | inline static int comp_mag_gt(COMP a, COMP b) { |
127 | return ((a.real*a.real)+(a.imag*a.imag)) > ((b.real*b.real)+(b.imag*b.imag)); | 123 | return ((a.real * a.real) + (a.imag * a.imag)) > |
124 | ((b.real * b.real) + (b.imag * b.imag)); | ||
128 | } | 125 | } |
129 | 126 | ||
130 | /* | 127 | /* |
131 | * Normalize a complex number's magnitude to 1 | 128 | * Normalize a complex number's magnitude to 1 |
132 | */ | 129 | */ |
133 | inline static COMP comp_normalize(COMP a){ | 130 | inline static COMP comp_normalize(COMP a) { |
134 | COMP b; | 131 | COMP b; |
135 | float av = cabsolute(a); | 132 | float av = cabsolute(a); |
136 | b.real = a.real/av; | 133 | b.real = a.real / av; |
137 | b.imag = a.imag/av; | 134 | b.imag = a.imag / av; |
138 | return b; | 135 | return b; |
139 | } | 136 | } |
140 | 137 | ||
141 | #endif | 138 | #endif |
@@ -30,96 +30,93 @@ | |||
30 | 30 | ||
31 | /*---------------------------------------------------------------------------*\ | 31 | /*---------------------------------------------------------------------------*\ |
32 | 32 | ||
33 | DEFINES | 33 | DEFINES |
34 | 34 | ||
35 | \*---------------------------------------------------------------------------*/ | 35 | \*---------------------------------------------------------------------------*/ |
36 | 36 | ||
37 | /* General defines */ | 37 | /* General defines */ |
38 | 38 | ||
39 | #define N_S 0.01 /* internal proc frame length in secs */ | 39 | #define N_S 0.01 /* internal proc frame length in secs */ |
40 | #define TW_S 0.005 /* trapezoidal synth window overlap */ | 40 | #define TW_S 0.005 /* trapezoidal synth window overlap */ |
41 | #define MAX_AMP 160 /* maximum number of harmonics */ | 41 | #define MAX_AMP 160 /* maximum number of harmonics */ |
42 | #ifndef PI | 42 | #ifndef PI |
43 | #define PI 3.141592654 /* mathematical constant */ | 43 | #define PI 3.141592654 /* mathematical constant */ |
44 | #endif | 44 | #endif |
45 | #define TWO_PI 6.283185307 /* mathematical constant */ | 45 | #ifndef M_PI |
46 | #define MAX_STR 2048 /* maximum string size */ | 46 | #define M_PI 3.14159265358979323846f |
47 | #endif | ||
48 | #define TWO_PI 6.283185307 /* mathematical constant */ | ||
49 | #define MAX_STR 2048 /* maximum string size */ | ||
47 | 50 | ||
48 | #define FFT_ENC 512 /* size of FFT used for encoder */ | 51 | #define FFT_ENC 512 /* size of FFT used for encoder */ |
49 | #define FFT_DEC 512 /* size of FFT used in decoder */ | 52 | #define FFT_DEC 512 /* size of FFT used in decoder */ |
50 | #define V_THRESH 6.0 /* voicing threshold in dB */ | 53 | #define V_THRESH 6.0 /* voicing threshold in dB */ |
51 | #define LPC_ORD 10 /* LPC order */ | 54 | #define LPC_ORD 10 /* LPC order */ |
52 | #define LPC_ORD_LOW 6 /* LPC order for lower rates */ | 55 | #define LPC_ORD_LOW 6 /* LPC order for lower rates */ |
53 | 56 | ||
54 | /* Pitch estimation defines */ | 57 | /* Pitch estimation defines */ |
55 | 58 | ||
56 | #define M_PITCH_S 0.0400 /* pitch analysis window in s */ | 59 | #define M_PITCH_S 0.0400 /* pitch analysis window in s */ |
57 | #define P_MIN_S 0.0025 /* minimum pitch period in s */ | 60 | #define P_MIN_S 0.0025 /* minimum pitch period in s */ |
58 | #define P_MAX_S 0.0200 /* maximum pitch period in s */ | 61 | #define P_MAX_S 0.0200 /* maximum pitch period in s */ |
59 | 62 | ||
60 | /*---------------------------------------------------------------------------*\ | 63 | /*---------------------------------------------------------------------------*\ |
61 | 64 | ||
62 | TYPEDEFS | 65 | TYPEDEFS |
63 | 66 | ||
64 | \*---------------------------------------------------------------------------*/ | 67 | \*---------------------------------------------------------------------------*/ |
65 | 68 | ||
66 | /* Structure to hold constants calculated at run time based on sample rate */ | 69 | /* Structure to hold constants calculated at run time based on sample rate */ |
67 | 70 | ||
68 | typedef struct { | 71 | typedef struct { |
69 | int Fs; /* sample rate of this instance */ | 72 | int Fs; /* sample rate of this instance */ |
70 | int n_samp; /* number of samples per 10ms frame at Fs */ | 73 | int n_samp; /* number of samples per 10ms frame at Fs */ |
71 | int max_amp; /* maximum number of harmonics */ | 74 | int max_amp; /* maximum number of harmonics */ |
72 | int m_pitch; /* pitch estimation window size in samples */ | 75 | int m_pitch; /* pitch estimation window size in samples */ |
73 | int p_min; /* minimum pitch period in samples */ | 76 | int p_min; /* minimum pitch period in samples */ |
74 | int p_max; /* maximum pitch period in samples */ | 77 | int p_max; /* maximum pitch period in samples */ |
75 | float Wo_min; | 78 | float Wo_min; |
76 | float Wo_max; | 79 | float Wo_max; |
77 | int nw; /* analysis window size in samples */ | 80 | int nw; /* analysis window size in samples */ |
78 | int tw; /* trapezoidal synthesis window overlap */ | 81 | int tw; /* trapezoidal synthesis window overlap */ |
79 | } C2CONST; | 82 | } C2CONST; |
80 | 83 | ||
81 | /* Structure to hold model parameters for one frame */ | 84 | /* Structure to hold model parameters for one frame */ |
82 | 85 | ||
83 | typedef struct { | 86 | typedef struct { |
84 | float Wo; /* fundamental frequency estimate in radians */ | 87 | float Wo; /* fundamental frequency estimate in radians */ |
85 | int L; /* number of harmonics */ | 88 | int L; /* number of harmonics */ |
86 | float A[MAX_AMP+1]; /* amplitiude of each harmonic */ | 89 | float A[MAX_AMP + 1]; /* amplitiude of each harmonic */ |
87 | float phi[MAX_AMP+1]; /* phase of each harmonic */ | 90 | float phi[MAX_AMP + 1]; /* phase of each harmonic */ |
88 | int voiced; /* non-zero if this frame is voiced */ | 91 | int voiced; /* non-zero if this frame is voiced */ |
89 | } MODEL; | 92 | } MODEL; |
90 | 93 | ||
91 | /* describes each codebook */ | 94 | /* describes each codebook */ |
92 | 95 | ||
93 | struct lsp_codebook { | 96 | struct lsp_codebook { |
94 | int k; /* dimension of vector */ | 97 | int k; /* dimension of vector */ |
95 | int log2m; /* number of bits in m */ | 98 | int log2m; /* number of bits in m */ |
96 | int m; /* elements in codebook */ | 99 | int m; /* elements in codebook */ |
97 | #ifdef __EMBEDDED /* make sure stored in flash */ | 100 | #ifdef __EMBEDDED__ /* make sure stored in flash */ |
98 | const float *cb; /* The elements */ | 101 | const float *cb; /* The elements */ |
99 | #else | 102 | #else |
100 | float *cb; /* The elements */ | 103 | float *cb; /* The elements */ |
101 | #endif | 104 | #endif |
102 | }; | 105 | }; |
103 | 106 | ||
104 | extern const struct lsp_codebook lsp_cb[]; | 107 | extern const struct lsp_codebook lsp_cb[]; |
105 | extern const struct lsp_codebook lsp_cbd[]; | 108 | extern const struct lsp_codebook lsp_cbd[]; |
106 | extern const struct lsp_codebook lsp_cbvq[]; | 109 | extern const struct lsp_codebook lsp_cbjmv[]; |
107 | extern const struct lsp_codebook lsp_cbjnd[]; | ||
108 | extern const struct lsp_codebook lsp_cbdt[]; | ||
109 | extern const struct lsp_codebook lsp_cbjvm[]; | ||
110 | extern const struct lsp_codebook lsp_cbvqanssi[]; | ||
111 | extern const struct lsp_codebook mel_cb[]; | ||
112 | extern const struct lsp_codebook ge_cb[]; | 110 | extern const struct lsp_codebook ge_cb[]; |
113 | extern const struct lsp_codebook lspmelvq_cb[]; | ||
114 | extern const struct lsp_codebook newamp1vq_cb[]; | 111 | extern const struct lsp_codebook newamp1vq_cb[]; |
115 | extern const struct lsp_codebook newamp1_energy_cb[]; | 112 | extern const struct lsp_codebook newamp1_energy_cb[]; |
116 | extern const struct lsp_codebook newamp2vq_cb[]; | 113 | extern const struct lsp_codebook newamp2vq_cb[]; |
117 | extern const struct lsp_codebook newamp2_energy_cb[]; | 114 | extern const struct lsp_codebook newamp2_energy_cb[]; |
118 | 115 | ||
119 | #ifdef _GNU_SOURCE | 116 | #ifdef _GNU_SOURCE |
120 | #define POW10F(x) exp10f((x)) | 117 | #define POW10F(x) exp10f((x)) |
121 | #else | 118 | #else |
122 | #define POW10F(x) expf(2.302585092994046f*(x)) | 119 | #define POW10F(x) expf(2.302585092994046f * (x)) |
123 | #endif | 120 | #endif |
124 | 121 | ||
125 | #endif | 122 | #endif |
@@ -25,13 +25,14 @@ | |||
25 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 25 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "interp.h" | ||
29 | |||
28 | #include <assert.h> | 30 | #include <assert.h> |
29 | #include <math.h> | 31 | #include <math.h> |
30 | #include <string.h> | ||
31 | #include <stdio.h> | 32 | #include <stdio.h> |
33 | #include <string.h> | ||
32 | 34 | ||
33 | #include "defines.h" | 35 | #include "defines.h" |
34 | #include "interp.h" | ||
35 | #include "lsp.h" | 36 | #include "lsp.h" |
36 | #include "quantise.h" | 37 | #include "quantise.h" |
37 | 38 | ||
@@ -44,7 +45,7 @@ float sample_log_amp(MODEL *model, float w); | |||
44 | AUTHOR......: David Rowe | 45 | AUTHOR......: David Rowe |
45 | DATE CREATED: 22/8/10 | 46 | DATE CREATED: 22/8/10 |
46 | 47 | ||
47 | Given two frames decribed by model parameters 20ms apart, determines | 48 | Given two frames described by model parameters 20ms apart, determines |
48 | the model parameters of the 10ms frame between them. Assumes | 49 | the model parameters of the 10ms frame between them. Assumes |
49 | voicing is available for middle (interpolated) frame. Outputs are | 50 | voicing is available for middle (interpolated) frame. Outputs are |
50 | amplitudes and Wo for the interpolated frame. | 51 | amplitudes and Wo for the interpolated frame. |
@@ -107,29 +108,27 @@ void interpolate( | |||
107 | 108 | ||
108 | \*---------------------------------------------------------------------------*/ | 109 | \*---------------------------------------------------------------------------*/ |
109 | 110 | ||
110 | float sample_log_amp(MODEL *model, float w) | 111 | float sample_log_amp(MODEL *model, float w) { |
111 | { | 112 | int m; |
112 | int m; | 113 | float f, log_amp; |
113 | float f, log_amp; | ||
114 | 114 | ||
115 | assert(w > 0.0); assert (w <= PI); | 115 | assert(w > 0.0); |
116 | assert(w <= PI); | ||
116 | 117 | ||
117 | m = floorf(w/model->Wo + 0.5); | 118 | m = floorf(w / model->Wo + 0.5); |
118 | f = (w - m*model->Wo)/w; | 119 | f = (w - m * model->Wo) / w; |
119 | assert(f <= 1.0); | 120 | assert(f <= 1.0); |
120 | 121 | ||
121 | if (m < 1) { | 122 | if (m < 1) { |
122 | log_amp = f*log10f(model->A[1] + 1E-6); | 123 | log_amp = f * log10f(model->A[1] + 1E-6); |
123 | } | 124 | } else if ((m + 1) > model->L) { |
124 | else if ((m+1) > model->L) { | 125 | log_amp = (1.0 - f) * log10f(model->A[model->L] + 1E-6); |
125 | log_amp = (1.0-f)*log10f(model->A[model->L] + 1E-6); | 126 | } else { |
126 | } | 127 | log_amp = (1.0 - f) * log10f(model->A[m] + 1E-6) + |
127 | else { | 128 | f * log10f(model->A[m + 1] + 1E-6); |
128 | log_amp = (1.0-f)*log10f(model->A[m] + 1E-6) + | 129 | } |
129 | f*log10f(model->A[m+1] + 1E-6); | ||
130 | } | ||
131 | 130 | ||
132 | return log_amp; | 131 | return log_amp; |
133 | } | 132 | } |
134 | 133 | ||
135 | #ifdef NOT_NEEDED | 134 | #ifdef NOT_NEEDED |
@@ -140,7 +139,7 @@ float sample_log_amp(MODEL *model, float w) | |||
140 | AUTHOR......: David Rowe | 139 | AUTHOR......: David Rowe |
141 | DATE CREATED: 10 Nov 2010 | 140 | DATE CREATED: 10 Nov 2010 |
142 | 141 | ||
143 | Given two frames decribed by model parameters 20ms apart, determines | 142 | Given two frames described by model parameters 20ms apart, determines |
144 | the model parameters of the 10ms frame between them. Assumes | 143 | the model parameters of the 10ms frame between them. Assumes |
145 | voicing is available for middle (interpolated) frame. Outputs are | 144 | voicing is available for middle (interpolated) frame. Outputs are |
146 | amplitudes and Wo for the interpolated frame. | 145 | amplitudes and Wo for the interpolated frame. |
@@ -150,65 +149,59 @@ float sample_log_amp(MODEL *model, float w) | |||
150 | 149 | ||
151 | \*---------------------------------------------------------------------------*/ | 150 | \*---------------------------------------------------------------------------*/ |
152 | 151 | ||
153 | void interpolate_lsp( | 152 | void interpolate_lsp(codec2_fft_cfg fft_fwd_cfg, |
154 | codec2_fft_cfg fft_fwd_cfg, | 153 | MODEL *interp, /* interpolated model params */ |
155 | MODEL *interp, /* interpolated model params */ | 154 | MODEL *prev, /* previous frames model params */ |
156 | MODEL *prev, /* previous frames model params */ | 155 | MODEL *next, /* next frames model params */ |
157 | MODEL *next, /* next frames model params */ | 156 | float *prev_lsps, /* previous frames LSPs */ |
158 | float *prev_lsps, /* previous frames LSPs */ | 157 | float prev_e, /* previous frames LPC energy */ |
159 | float prev_e, /* previous frames LPC energy */ | 158 | float *next_lsps, /* next frames LSPs */ |
160 | float *next_lsps, /* next frames LSPs */ | 159 | float next_e, /* next frames LPC energy */ |
161 | float next_e, /* next frames LPC energy */ | 160 | float *ak_interp, /* interpolated aks for this frame */ |
162 | float *ak_interp, /* interpolated aks for this frame */ | 161 | float *lsps_interp, /* interpolated lsps for this frame */ |
163 | float *lsps_interp, /* interpolated lsps for this frame */ | 162 | float Wo_min) { |
164 | float Wo_min | 163 | int i; |
165 | ) | 164 | float e; |
166 | { | 165 | float snr; |
167 | int i; | 166 | |
168 | float e; | 167 | /* trap corner case where V est is probably wrong */ |
169 | float snr; | 168 | |
170 | 169 | if (interp->voiced && !prev->voiced && !next->voiced) { | |
171 | /* trap corner case where V est is probably wrong */ | 170 | interp->voiced = 0; |
172 | 171 | } | |
173 | if (interp->voiced && !prev->voiced && !next->voiced) { | 172 | |
174 | interp->voiced = 0; | 173 | /* Wo depends on voicing of this and adjacent frames */ |
175 | } | 174 | |
176 | 175 | if (interp->voiced) { | |
177 | /* Wo depends on voicing of this and adjacent frames */ | 176 | if (prev->voiced && next->voiced) interp->Wo = (prev->Wo + next->Wo) / 2.0; |
178 | 177 | if (!prev->voiced && next->voiced) interp->Wo = next->Wo; | |
179 | if (interp->voiced) { | 178 | if (prev->voiced && !next->voiced) interp->Wo = prev->Wo; |
180 | if (prev->voiced && next->voiced) | 179 | } else { |
181 | interp->Wo = (prev->Wo + next->Wo)/2.0; | 180 | interp->Wo = Wo_min; |
182 | if (!prev->voiced && next->voiced) | 181 | } |
183 | interp->Wo = next->Wo; | 182 | interp->L = PI / interp->Wo; |
184 | if (prev->voiced && !next->voiced) | 183 | |
185 | interp->Wo = prev->Wo; | 184 | // printf(" interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n", |
186 | } | 185 | // prev->voiced, next->voiced, prev->Wo, next->Wo); |
187 | else { | 186 | // printf(" interp: Wo: %1.5f L: %d\n", interp->Wo, interp->L); |
188 | interp->Wo = Wo_min; | 187 | |
189 | } | 188 | /* interpolate LSPs */ |
190 | interp->L = PI/interp->Wo; | 189 | |
191 | 190 | for (i = 0; i < LPC_ORD; i++) { | |
192 | //printf(" interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n", | 191 | lsps_interp[i] = (prev_lsps[i] + next_lsps[i]) / 2.0; |
193 | // prev->voiced, next->voiced, prev->Wo, next->Wo); | 192 | } |
194 | //printf(" interp: Wo: %1.5f L: %d\n", interp->Wo, interp->L); | 193 | |
195 | 194 | /* Interpolate LPC energy in log domain */ | |
196 | /* interpolate LSPs */ | 195 | |
197 | 196 | e = powf(10.0, (log10f(prev_e) + log10f(next_e)) / 2.0); | |
198 | for(i=0; i<LPC_ORD; i++) { | 197 | // printf(" interp: e: %f\n", e); |
199 | lsps_interp[i] = (prev_lsps[i] + next_lsps[i])/2.0; | 198 | |
200 | } | 199 | /* convert back to amplitudes */ |
201 | 200 | ||
202 | /* Interpolate LPC energy in log domain */ | 201 | lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD); |
203 | 202 | aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, | |
204 | e = powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); | 203 | LPCPF_BETA, LPCPF_GAMMA); |
205 | //printf(" interp: e: %f\n", e); | 204 | // printf(" interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]); |
206 | |||
207 | /* convert back to amplitudes */ | ||
208 | |||
209 | lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD); | ||
210 | aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); | ||
211 | //printf(" interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]); | ||
212 | } | 205 | } |
213 | #endif | 206 | #endif |
214 | 207 | ||
@@ -224,14 +217,11 @@ void interpolate_lsp( | |||
224 | 217 | ||
225 | \*---------------------------------------------------------------------------*/ | 218 | \*---------------------------------------------------------------------------*/ |
226 | 219 | ||
227 | void interp_Wo( | 220 | void interp_Wo(MODEL *interp, /* interpolated model params */ |
228 | MODEL *interp, /* interpolated model params */ | 221 | MODEL *prev, /* previous frames model params */ |
229 | MODEL *prev, /* previous frames model params */ | 222 | MODEL *next, /* next frames model params */ |
230 | MODEL *next, /* next frames model params */ | 223 | float Wo_min) { |
231 | float Wo_min | 224 | interp_Wo2(interp, prev, next, 0.5, Wo_min); |
232 | ) | ||
233 | { | ||
234 | interp_Wo2(interp, prev, next, 0.5, Wo_min); | ||
235 | } | 225 | } |
236 | 226 | ||
237 | /*---------------------------------------------------------------------------*\ | 227 | /*---------------------------------------------------------------------------*\ |
@@ -244,37 +234,29 @@ void interp_Wo( | |||
244 | 234 | ||
245 | \*---------------------------------------------------------------------------*/ | 235 | \*---------------------------------------------------------------------------*/ |
246 | 236 | ||
247 | void interp_Wo2( | 237 | void interp_Wo2(MODEL *interp, /* interpolated model params */ |
248 | MODEL *interp, /* interpolated model params */ | 238 | MODEL *prev, /* previous frames model params */ |
249 | MODEL *prev, /* previous frames model params */ | 239 | MODEL *next, /* next frames model params */ |
250 | MODEL *next, /* next frames model params */ | 240 | float weight, float Wo_min) { |
251 | float weight, | 241 | /* trap corner case where voicing est is probably wrong */ |
252 | float Wo_min | 242 | |
253 | ) | 243 | if (interp->voiced && !prev->voiced && !next->voiced) { |
254 | { | 244 | interp->voiced = 0; |
255 | /* trap corner case where voicing est is probably wrong */ | 245 | } |
256 | 246 | ||
257 | if (interp->voiced && !prev->voiced && !next->voiced) { | 247 | /* Wo depends on voicing of this and adjacent frames */ |
258 | interp->voiced = 0; | 248 | |
259 | } | 249 | if (interp->voiced) { |
260 | 250 | if (prev->voiced && next->voiced) | |
261 | /* Wo depends on voicing of this and adjacent frames */ | 251 | interp->Wo = (1.0 - weight) * prev->Wo + weight * next->Wo; |
262 | 252 | if (!prev->voiced && next->voiced) interp->Wo = next->Wo; | |
263 | if (interp->voiced) { | 253 | if (prev->voiced && !next->voiced) interp->Wo = prev->Wo; |
264 | if (prev->voiced && next->voiced) | 254 | } else { |
265 | interp->Wo = (1.0 - weight)*prev->Wo + weight*next->Wo; | 255 | interp->Wo = Wo_min; |
266 | if (!prev->voiced && next->voiced) | 256 | } |
267 | interp->Wo = next->Wo; | 257 | interp->L = PI / interp->Wo; |
268 | if (prev->voiced && !next->voiced) | ||
269 | interp->Wo = prev->Wo; | ||
270 | } | ||
271 | else { | ||
272 | interp->Wo = Wo_min; | ||
273 | } | ||
274 | interp->L = PI/interp->Wo; | ||
275 | } | 258 | } |
276 | 259 | ||
277 | |||
278 | /*---------------------------------------------------------------------------*\ | 260 | /*---------------------------------------------------------------------------*\ |
279 | 261 | ||
280 | FUNCTION....: interp_energy() | 262 | FUNCTION....: interp_energy() |
@@ -286,13 +268,12 @@ void interp_Wo2( | |||
286 | 268 | ||
287 | \*---------------------------------------------------------------------------*/ | 269 | \*---------------------------------------------------------------------------*/ |
288 | 270 | ||
289 | float interp_energy(float prev_e, float next_e) | 271 | float interp_energy(float prev_e, float next_e) { |
290 | { | 272 | // return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); |
291 | //return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); | 273 | return sqrtf(prev_e * |
292 | return sqrtf(prev_e * next_e); //looks better is math. identical and faster math | 274 | next_e); // looks better is math. identical and faster math |
293 | } | 275 | } |
294 | 276 | ||
295 | |||
296 | /*---------------------------------------------------------------------------*\ | 277 | /*---------------------------------------------------------------------------*\ |
297 | 278 | ||
298 | FUNCTION....: interp_energy2() | 279 | FUNCTION....: interp_energy2() |
@@ -304,13 +285,10 @@ float interp_energy(float prev_e, float next_e) | |||
304 | 285 | ||
305 | \*---------------------------------------------------------------------------*/ | 286 | \*---------------------------------------------------------------------------*/ |
306 | 287 | ||
307 | float interp_energy2(float prev_e, float next_e, float weight) | 288 | float interp_energy2(float prev_e, float next_e, float weight) { |
308 | { | 289 | return POW10F((1.0 - weight) * log10f(prev_e) + weight * log10f(next_e)); |
309 | return POW10F((1.0 - weight)*log10f(prev_e) + weight*log10f(next_e)); | ||
310 | |||
311 | } | 290 | } |
312 | 291 | ||
313 | |||
314 | /*---------------------------------------------------------------------------*\ | 292 | /*---------------------------------------------------------------------------*\ |
315 | 293 | ||
316 | FUNCTION....: interpolate_lsp_ver2() | 294 | FUNCTION....: interpolate_lsp_ver2() |
@@ -321,11 +299,10 @@ float interp_energy2(float prev_e, float next_e, float weight) | |||
321 | 299 | ||
322 | \*---------------------------------------------------------------------------*/ | 300 | \*---------------------------------------------------------------------------*/ |
323 | 301 | ||
324 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight, int order) | 302 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], |
325 | { | 303 | float weight, int order) { |
326 | int i; | 304 | int i; |
327 | 305 | ||
328 | for(i=0; i<order; i++) | 306 | for (i = 0; i < order; i++) |
329 | interp[i] = (1.0 - weight)*prev[i] + weight*next[i]; | 307 | interp[i] = (1.0 - weight) * prev[i] + weight * next[i]; |
330 | } | 308 | } |
331 | |||
@@ -28,18 +28,20 @@ | |||
28 | #ifndef __INTERP__ | 28 | #ifndef __INTERP__ |
29 | #define __INTERP__ | 29 | #define __INTERP__ |
30 | 30 | ||
31 | #include "defines.h" | ||
31 | #include "kiss_fft.h" | 32 | #include "kiss_fft.h" |
32 | 33 | ||
33 | void interpolate(MODEL *interp, MODEL *prev, MODEL *next); | 34 | void interpolate(MODEL *interp, MODEL *prev, MODEL *next); |
34 | void interpolate_lsp(kiss_fft_cfg fft_dec_cfg, | 35 | void interpolate_lsp(kiss_fft_cfg fft_dec_cfg, MODEL *interp, MODEL *prev, |
35 | MODEL *interp, MODEL *prev, MODEL *next, | 36 | MODEL *next, float *prev_lsps, float prev_e, |
36 | float *prev_lsps, float prev_e, | 37 | float *next_lsps, float next_e, float *ak_interp, |
37 | float *next_lsps, float next_e, | 38 | float *lsps_interp, float Wo_min); |
38 | float *ak_interp, float *lsps_interp, float Wo_min); | ||
39 | void interp_Wo(MODEL *interp, MODEL *prev, MODEL *next, float Wo_min); | 39 | void interp_Wo(MODEL *interp, MODEL *prev, MODEL *next, float Wo_min); |
40 | void interp_Wo2(MODEL *interp, MODEL *prev, MODEL *next, float weight, float Wo_min); | 40 | void interp_Wo2(MODEL *interp, MODEL *prev, MODEL *next, float weight, |
41 | float Wo_min); | ||
41 | float interp_energy(float prev, float next); | 42 | float interp_energy(float prev, float next); |
42 | float interp_energy2(float prev, float next, float weight); | 43 | float interp_energy2(float prev, float next, float weight); |
43 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight, int order); | 44 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], |
45 | float weight, int order); | ||
44 | 46 | ||
45 | #endif | 47 | #endif |
@@ -3,406 +3,424 @@ Copyright (c) 2003-2010, Mark Borgerding | |||
3 | 3 | ||
4 | All rights reserved. | 4 | All rights reserved. |
5 | 5 | ||
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | 6 | Redistribution and use in source and binary forms, with or without modification, |
7 | 7 | are permitted provided that the following conditions are met: | |
8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | 8 | |
9 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | 9 | * Redistributions of source code must retain the above copyright notice, |
10 | * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. | 10 | this list of conditions and the following disclaimer. |
11 | 11 | * Redistributions in binary form must reproduce the above copyright notice, | |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 12 | this list of conditions and the following disclaimer in the documentation and/or |
13 | other materials provided with the distribution. | ||
14 | * Neither the author nor the names of any contributors may be used to | ||
15 | endorse or promote products derived from this software without specific prior | ||
16 | written permission. | ||
17 | |||
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
13 | */ | 28 | */ |
14 | 29 | ||
15 | |||
16 | #include "_kiss_fft_guts.h" | 30 | #include "_kiss_fft_guts.h" |
17 | /* The guts header contains all the multiplication and addition macros that are defined for | 31 | /* The guts header contains all the multiplication and addition macros that are |
18 | fixed or floating point complex numbers. It also delares the kf_ internal functions. | 32 | defined for fixed or floating point complex numbers. It also declares the kf_ |
33 | internal functions. | ||
19 | */ | 34 | */ |
20 | 35 | ||
21 | static void kf_bfly2( | 36 | static void kf_bfly2(kiss_fft_cpx *Fout, const size_t fstride, |
22 | kiss_fft_cpx * Fout, | 37 | const kiss_fft_cfg st, int m) { |
23 | const size_t fstride, | 38 | kiss_fft_cpx *Fout2; |
24 | const kiss_fft_cfg st, | 39 | kiss_fft_cpx *tw1 = st->twiddles; |
25 | int m | 40 | kiss_fft_cpx t; |
26 | ) | 41 | Fout2 = Fout + m; |
27 | { | 42 | do { |
28 | kiss_fft_cpx * Fout2; | 43 | C_FIXDIV(*Fout, 2); |
29 | kiss_fft_cpx * tw1 = st->twiddles; | 44 | C_FIXDIV(*Fout2, 2); |
30 | kiss_fft_cpx t; | 45 | |
31 | Fout2 = Fout + m; | 46 | C_MUL(t, *Fout2, *tw1); |
32 | do{ | 47 | tw1 += fstride; |
33 | C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); | 48 | C_SUB(*Fout2, *Fout, t); |
34 | 49 | C_ADDTO(*Fout, t); | |
35 | C_MUL (t, *Fout2 , *tw1); | 50 | ++Fout2; |
36 | tw1 += fstride; | 51 | ++Fout; |
37 | C_SUB( *Fout2 , *Fout , t ); | 52 | } while (--m); |
38 | C_ADDTO( *Fout , t ); | ||
39 | ++Fout2; | ||
40 | ++Fout; | ||
41 | }while (--m); | ||
42 | } | 53 | } |
43 | 54 | ||
44 | static void kf_bfly4( | 55 | static void kf_bfly4(kiss_fft_cpx *Fout, const size_t fstride, |
45 | kiss_fft_cpx * Fout, | 56 | const kiss_fft_cfg st, const size_t m) { |
46 | const size_t fstride, | 57 | kiss_fft_cpx *tw1, *tw2, *tw3; |
47 | const kiss_fft_cfg st, | 58 | kiss_fft_cpx scratch[6]; |
48 | const size_t m | 59 | size_t k = m; |
49 | ) | 60 | const size_t m2 = 2 * m; |
50 | { | 61 | const size_t m3 = 3 * m; |
51 | kiss_fft_cpx *tw1,*tw2,*tw3; | 62 | |
52 | kiss_fft_cpx scratch[6]; | 63 | tw3 = tw2 = tw1 = st->twiddles; |
53 | size_t k=m; | 64 | |
54 | const size_t m2=2*m; | 65 | do { |
55 | const size_t m3=3*m; | 66 | C_FIXDIV(*Fout, 4); |
56 | 67 | C_FIXDIV(Fout[m], 4); | |
57 | 68 | C_FIXDIV(Fout[m2], 4); | |
58 | tw3 = tw2 = tw1 = st->twiddles; | 69 | C_FIXDIV(Fout[m3], 4); |
59 | 70 | ||
60 | do { | 71 | C_MUL(scratch[0], Fout[m], *tw1); |
61 | C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); | 72 | C_MUL(scratch[1], Fout[m2], *tw2); |
62 | 73 | C_MUL(scratch[2], Fout[m3], *tw3); | |
63 | C_MUL(scratch[0],Fout[m] , *tw1 ); | 74 | |
64 | C_MUL(scratch[1],Fout[m2] , *tw2 ); | 75 | C_SUB(scratch[5], *Fout, scratch[1]); |
65 | C_MUL(scratch[2],Fout[m3] , *tw3 ); | 76 | C_ADDTO(*Fout, scratch[1]); |
66 | 77 | C_ADD(scratch[3], scratch[0], scratch[2]); | |
67 | C_SUB( scratch[5] , *Fout, scratch[1] ); | 78 | C_SUB(scratch[4], scratch[0], scratch[2]); |
68 | C_ADDTO(*Fout, scratch[1]); | 79 | C_SUB(Fout[m2], *Fout, scratch[3]); |
69 | C_ADD( scratch[3] , scratch[0] , scratch[2] ); | 80 | tw1 += fstride; |
70 | C_SUB( scratch[4] , scratch[0] , scratch[2] ); | 81 | tw2 += fstride * 2; |
71 | C_SUB( Fout[m2], *Fout, scratch[3] ); | 82 | tw3 += fstride * 3; |
72 | tw1 += fstride; | 83 | C_ADDTO(*Fout, scratch[3]); |
73 | tw2 += fstride*2; | 84 | |
74 | tw3 += fstride*3; | 85 | if (st->inverse) { |
75 | C_ADDTO( *Fout , scratch[3] ); | 86 | Fout[m].r = scratch[5].r - scratch[4].i; |
76 | 87 | Fout[m].i = scratch[5].i + scratch[4].r; | |
77 | if(st->inverse) { | 88 | Fout[m3].r = scratch[5].r + scratch[4].i; |
78 | Fout[m].r = scratch[5].r - scratch[4].i; | 89 | Fout[m3].i = scratch[5].i - scratch[4].r; |
79 | Fout[m].i = scratch[5].i + scratch[4].r; | 90 | } else { |
80 | Fout[m3].r = scratch[5].r + scratch[4].i; | 91 | Fout[m].r = scratch[5].r + scratch[4].i; |
81 | Fout[m3].i = scratch[5].i - scratch[4].r; | 92 | Fout[m].i = scratch[5].i - scratch[4].r; |
82 | }else{ | 93 | Fout[m3].r = scratch[5].r - scratch[4].i; |
83 | Fout[m].r = scratch[5].r + scratch[4].i; | 94 | Fout[m3].i = scratch[5].i + scratch[4].r; |
84 | Fout[m].i = scratch[5].i - scratch[4].r; | 95 | } |
85 | Fout[m3].r = scratch[5].r - scratch[4].i; | 96 | ++Fout; |
86 | Fout[m3].i = scratch[5].i + scratch[4].r; | 97 | } while (--k); |
87 | } | ||
88 | ++Fout; | ||
89 | }while(--k); | ||
90 | } | 98 | } |
91 | 99 | ||
92 | static void kf_bfly3( | 100 | static void kf_bfly3(kiss_fft_cpx *Fout, const size_t fstride, |
93 | kiss_fft_cpx * Fout, | 101 | const kiss_fft_cfg st, size_t m) { |
94 | const size_t fstride, | 102 | size_t k = m; |
95 | const kiss_fft_cfg st, | 103 | const size_t m2 = 2 * m; |
96 | size_t m | 104 | kiss_fft_cpx *tw1, *tw2; |
97 | ) | 105 | kiss_fft_cpx scratch[5]; |
98 | { | 106 | kiss_fft_cpx epi3; |
99 | size_t k=m; | 107 | epi3 = st->twiddles[fstride * m]; |
100 | const size_t m2 = 2*m; | ||
101 | kiss_fft_cpx *tw1,*tw2; | ||
102 | kiss_fft_cpx scratch[5]; | ||
103 | kiss_fft_cpx epi3; | ||
104 | epi3 = st->twiddles[fstride*m]; | ||
105 | 108 | ||
106 | tw1=tw2=st->twiddles; | 109 | tw1 = tw2 = st->twiddles; |
107 | 110 | ||
108 | do{ | 111 | do { |
109 | C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); | 112 | C_FIXDIV(*Fout, 3); |
113 | C_FIXDIV(Fout[m], 3); | ||
114 | C_FIXDIV(Fout[m2], 3); | ||
110 | 115 | ||
111 | C_MUL(scratch[1],Fout[m] , *tw1); | 116 | C_MUL(scratch[1], Fout[m], *tw1); |
112 | C_MUL(scratch[2],Fout[m2] , *tw2); | 117 | C_MUL(scratch[2], Fout[m2], *tw2); |
113 | 118 | ||
114 | C_ADD(scratch[3],scratch[1],scratch[2]); | 119 | C_ADD(scratch[3], scratch[1], scratch[2]); |
115 | C_SUB(scratch[0],scratch[1],scratch[2]); | 120 | C_SUB(scratch[0], scratch[1], scratch[2]); |
116 | tw1 += fstride; | 121 | tw1 += fstride; |
117 | tw2 += fstride*2; | 122 | tw2 += fstride * 2; |
118 | 123 | ||
119 | Fout[m].r = Fout->r - HALF_OF(scratch[3].r); | 124 | Fout[m].r = Fout->r - HALF_OF(scratch[3].r); |
120 | Fout[m].i = Fout->i - HALF_OF(scratch[3].i); | 125 | Fout[m].i = Fout->i - HALF_OF(scratch[3].i); |
121 | 126 | ||
122 | C_MULBYSCALAR( scratch[0] , epi3.i ); | 127 | C_MULBYSCALAR(scratch[0], epi3.i); |
123 | 128 | ||
124 | C_ADDTO(*Fout,scratch[3]); | 129 | C_ADDTO(*Fout, scratch[3]); |
125 | 130 | ||
126 | Fout[m2].r = Fout[m].r + scratch[0].i; | 131 | Fout[m2].r = Fout[m].r + scratch[0].i; |
127 | Fout[m2].i = Fout[m].i - scratch[0].r; | 132 | Fout[m2].i = Fout[m].i - scratch[0].r; |
128 | 133 | ||
129 | Fout[m].r -= scratch[0].i; | 134 | Fout[m].r -= scratch[0].i; |
130 | Fout[m].i += scratch[0].r; | 135 | Fout[m].i += scratch[0].r; |
131 | 136 | ||
132 | ++Fout; | 137 | ++Fout; |
133 | }while(--k); | 138 | } while (--k); |
134 | } | 139 | } |
135 | 140 | ||
136 | static void kf_bfly5( | 141 | static void kf_bfly5(kiss_fft_cpx *Fout, const size_t fstride, |
137 | kiss_fft_cpx * Fout, | 142 | const kiss_fft_cfg st, int m) { |
138 | const size_t fstride, | 143 | kiss_fft_cpx *Fout0, *Fout1, *Fout2, *Fout3, *Fout4; |
139 | const kiss_fft_cfg st, | 144 | int u; |
140 | int m | 145 | kiss_fft_cpx scratch[13]; |
141 | ) | 146 | kiss_fft_cpx *twiddles = st->twiddles; |
142 | { | 147 | kiss_fft_cpx *tw; |
143 | kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; | 148 | kiss_fft_cpx ya, yb; |
144 | int u; | 149 | ya = twiddles[fstride * m]; |
145 | kiss_fft_cpx scratch[13]; | 150 | yb = twiddles[fstride * 2 * m]; |
146 | kiss_fft_cpx * twiddles = st->twiddles; | 151 | |
147 | kiss_fft_cpx *tw; | 152 | Fout0 = Fout; |
148 | kiss_fft_cpx ya,yb; | 153 | Fout1 = Fout0 + m; |
149 | ya = twiddles[fstride*m]; | 154 | Fout2 = Fout0 + 2 * m; |
150 | yb = twiddles[fstride*2*m]; | 155 | Fout3 = Fout0 + 3 * m; |
151 | 156 | Fout4 = Fout0 + 4 * m; | |
152 | Fout0=Fout; | 157 | |
153 | Fout1=Fout0+m; | 158 | tw = st->twiddles; |
154 | Fout2=Fout0+2*m; | 159 | for (u = 0; u < m; ++u) { |
155 | Fout3=Fout0+3*m; | 160 | C_FIXDIV(*Fout0, 5); |
156 | Fout4=Fout0+4*m; | 161 | C_FIXDIV(*Fout1, 5); |
157 | 162 | C_FIXDIV(*Fout2, 5); | |
158 | tw=st->twiddles; | 163 | C_FIXDIV(*Fout3, 5); |
159 | for ( u=0; u<m; ++u ) { | 164 | C_FIXDIV(*Fout4, 5); |
160 | C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5); | 165 | scratch[0] = *Fout0; |
161 | scratch[0] = *Fout0; | 166 | |
162 | 167 | C_MUL(scratch[1], *Fout1, tw[u * fstride]); | |
163 | C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); | 168 | C_MUL(scratch[2], *Fout2, tw[2 * u * fstride]); |
164 | C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); | 169 | C_MUL(scratch[3], *Fout3, tw[3 * u * fstride]); |
165 | C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); | 170 | C_MUL(scratch[4], *Fout4, tw[4 * u * fstride]); |
166 | C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); | 171 | |
167 | 172 | C_ADD(scratch[7], scratch[1], scratch[4]); | |
168 | C_ADD( scratch[7],scratch[1],scratch[4]); | 173 | C_SUB(scratch[10], scratch[1], scratch[4]); |
169 | C_SUB( scratch[10],scratch[1],scratch[4]); | 174 | C_ADD(scratch[8], scratch[2], scratch[3]); |
170 | C_ADD( scratch[8],scratch[2],scratch[3]); | 175 | C_SUB(scratch[9], scratch[2], scratch[3]); |
171 | C_SUB( scratch[9],scratch[2],scratch[3]); | 176 | |
172 | 177 | Fout0->r += scratch[7].r + scratch[8].r; | |
173 | Fout0->r += scratch[7].r + scratch[8].r; | 178 | Fout0->i += scratch[7].i + scratch[8].i; |
174 | Fout0->i += scratch[7].i + scratch[8].i; | 179 | |
175 | 180 | scratch[5].r = | |
176 | scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); | 181 | scratch[0].r + S_MUL(scratch[7].r, ya.r) + S_MUL(scratch[8].r, yb.r); |
177 | scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); | 182 | scratch[5].i = |
178 | 183 | scratch[0].i + S_MUL(scratch[7].i, ya.r) + S_MUL(scratch[8].i, yb.r); | |
179 | scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); | 184 | |
180 | scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); | 185 | scratch[6].r = S_MUL(scratch[10].i, ya.i) + S_MUL(scratch[9].i, yb.i); |
181 | 186 | scratch[6].i = -S_MUL(scratch[10].r, ya.i) - S_MUL(scratch[9].r, yb.i); | |
182 | C_SUB(*Fout1,scratch[5],scratch[6]); | 187 | |
183 | C_ADD(*Fout4,scratch[5],scratch[6]); | 188 | C_SUB(*Fout1, scratch[5], scratch[6]); |
184 | 189 | C_ADD(*Fout4, scratch[5], scratch[6]); | |
185 | scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); | 190 | |
186 | scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); | 191 | scratch[11].r = |
187 | scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); | 192 | scratch[0].r + S_MUL(scratch[7].r, yb.r) + S_MUL(scratch[8].r, ya.r); |
188 | scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); | 193 | scratch[11].i = |
189 | 194 | scratch[0].i + S_MUL(scratch[7].i, yb.r) + S_MUL(scratch[8].i, ya.r); | |
190 | C_ADD(*Fout2,scratch[11],scratch[12]); | 195 | scratch[12].r = -S_MUL(scratch[10].i, yb.i) + S_MUL(scratch[9].i, ya.i); |
191 | C_SUB(*Fout3,scratch[11],scratch[12]); | 196 | scratch[12].i = S_MUL(scratch[10].r, yb.i) - S_MUL(scratch[9].r, ya.i); |
192 | 197 | ||
193 | ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; | 198 | C_ADD(*Fout2, scratch[11], scratch[12]); |
194 | } | 199 | C_SUB(*Fout3, scratch[11], scratch[12]); |
200 | |||
201 | ++Fout0; | ||
202 | ++Fout1; | ||
203 | ++Fout2; | ||
204 | ++Fout3; | ||
205 | ++Fout4; | ||
206 | } | ||
195 | } | 207 | } |
196 | 208 | ||
197 | /* perform the butterfly for one stage of a mixed radix FFT */ | 209 | /* perform the butterfly for one stage of a mixed radix FFT */ |
198 | static void kf_bfly_generic( | 210 | static void kf_bfly_generic(kiss_fft_cpx *Fout, const size_t fstride, |
199 | kiss_fft_cpx * Fout, | 211 | const kiss_fft_cfg st, int m, int p) { |
200 | const size_t fstride, | 212 | int u, k, q1, q; |
201 | const kiss_fft_cfg st, | 213 | kiss_fft_cpx *twiddles = st->twiddles; |
202 | int m, | 214 | kiss_fft_cpx t; |
203 | int p | 215 | int Norig = st->nfft; |
204 | ) | 216 | |
205 | { | 217 | kiss_fft_cpx *scratch = |
206 | int u,k,q1,q; | 218 | (kiss_fft_cpx *)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx) * p); |
207 | kiss_fft_cpx * twiddles = st->twiddles; | 219 | |
208 | kiss_fft_cpx t; | 220 | for (u = 0; u < m; ++u) { |
209 | int Norig = st->nfft; | 221 | k = u; |
210 | 222 | for (q1 = 0; q1 < p; ++q1) { | |
211 | kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); | 223 | scratch[q1] = Fout[k]; |
212 | 224 | C_FIXDIV(scratch[q1], p); | |
213 | for ( u=0; u<m; ++u ) { | 225 | k += m; |
214 | k=u; | ||
215 | for ( q1=0 ; q1<p ; ++q1 ) { | ||
216 | scratch[q1] = Fout[ k ]; | ||
217 | C_FIXDIV(scratch[q1],p); | ||
218 | k += m; | ||
219 | } | ||
220 | |||
221 | k=u; | ||
222 | for ( q1=0 ; q1<p ; ++q1 ) { | ||
223 | int twidx=0; | ||
224 | Fout[ k ] = scratch[0]; | ||
225 | for (q=1;q<p;++q ) { | ||
226 | twidx += fstride * k; | ||
227 | if (twidx>=Norig) twidx-=Norig; | ||
228 | C_MUL(t,scratch[q] , twiddles[twidx] ); | ||
229 | C_ADDTO( Fout[ k ] ,t); | ||
230 | } | ||
231 | k += m; | ||
232 | } | ||
233 | } | 226 | } |
234 | KISS_FFT_TMP_FREE(scratch); | ||
235 | } | ||
236 | |||
237 | static | ||
238 | void kf_work( | ||
239 | kiss_fft_cpx * Fout, | ||
240 | const kiss_fft_cpx * f, | ||
241 | const size_t fstride, | ||
242 | int in_stride, | ||
243 | int * factors, | ||
244 | const kiss_fft_cfg st | ||
245 | ) | ||
246 | { | ||
247 | kiss_fft_cpx * Fout_beg=Fout; | ||
248 | const int p=*factors++; /* the radix */ | ||
249 | const int m=*factors++; /* stage's fft length/p */ | ||
250 | const kiss_fft_cpx * Fout_end = Fout + p*m; | ||
251 | 227 | ||
252 | #ifdef _OPENMP | 228 | k = u; |
253 | // use openmp extensions at the | 229 | for (q1 = 0; q1 < p; ++q1) { |
254 | // top-level (not recursive) | 230 | int twidx = 0; |
255 | if (fstride==1 && p<=5) | 231 | Fout[k] = scratch[0]; |
256 | { | 232 | for (q = 1; q < p; ++q) { |
257 | int k; | 233 | twidx += fstride * k; |
258 | 234 | if (twidx >= Norig) twidx -= Norig; | |
259 | // execute the p different work units in different threads | 235 | C_MUL(t, scratch[q], twiddles[twidx]); |
260 | # pragma omp parallel for | 236 | C_ADDTO(Fout[k], t); |
261 | for (k=0;k<p;++k) | 237 | } |
262 | kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st); | 238 | k += m; |
263 | // all threads have joined by this point | ||
264 | |||
265 | switch (p) { | ||
266 | case 2: kf_bfly2(Fout,fstride,st,m); break; | ||
267 | case 3: kf_bfly3(Fout,fstride,st,m); break; | ||
268 | case 4: kf_bfly4(Fout,fstride,st,m); break; | ||
269 | case 5: kf_bfly5(Fout,fstride,st,m); break; | ||
270 | default: kf_bfly_generic(Fout,fstride,st,m,p); break; | ||
271 | } | ||
272 | return; | ||
273 | } | 239 | } |
274 | #endif | 240 | } |
241 | KISS_FFT_TMP_FREE(scratch); | ||
242 | } | ||
275 | 243 | ||
276 | if (m==1) { | 244 | static void kf_work(kiss_fft_cpx *Fout, const kiss_fft_cpx *f, |
277 | do{ | 245 | const size_t fstride, int in_stride, int *factors, |
278 | *Fout = *f; | 246 | const kiss_fft_cfg st) { |
279 | f += fstride*in_stride; | 247 | kiss_fft_cpx *Fout_beg = Fout; |
280 | }while(++Fout != Fout_end ); | 248 | const int p = *factors++; /* the radix */ |
281 | }else{ | 249 | const int m = *factors++; /* stage's fft length/p */ |
282 | do{ | 250 | const kiss_fft_cpx *Fout_end = Fout + p * m; |
283 | // recursive call: | ||
284 | // DFT of size m*p performed by doing | ||
285 | // p instances of smaller DFTs of size m, | ||
286 | // each one takes a decimated version of the input | ||
287 | kf_work( Fout , f, fstride*p, in_stride, factors,st); | ||
288 | f += fstride*in_stride; | ||
289 | }while( (Fout += m) != Fout_end ); | ||
290 | } | ||
291 | 251 | ||
292 | Fout=Fout_beg; | 252 | #ifdef _OPENMP |
253 | // use openmp extensions at the | ||
254 | // top-level (not recursive) | ||
255 | if (fstride == 1 && p <= 5) { | ||
256 | int k; | ||
257 | |||
258 | // execute the p different work units in different threads | ||
259 | #pragma omp parallel for | ||
260 | for (k = 0; k < p; ++k) | ||
261 | kf_work(Fout + k * m, f + fstride * in_stride * k, fstride * p, in_stride, | ||
262 | factors, st); | ||
263 | // all threads have joined by this point | ||
293 | 264 | ||
294 | // recombine the p smaller DFTs | ||
295 | switch (p) { | 265 | switch (p) { |
296 | case 2: kf_bfly2(Fout,fstride,st,m); break; | 266 | case 2: |
297 | case 3: kf_bfly3(Fout,fstride,st,m); break; | 267 | kf_bfly2(Fout, fstride, st, m); |
298 | case 4: kf_bfly4(Fout,fstride,st,m); break; | 268 | break; |
299 | case 5: kf_bfly5(Fout,fstride,st,m); break; | 269 | case 3: |
300 | default: kf_bfly_generic(Fout,fstride,st,m,p); break; | 270 | kf_bfly3(Fout, fstride, st, m); |
271 | break; | ||
272 | case 4: | ||
273 | kf_bfly4(Fout, fstride, st, m); | ||
274 | break; | ||
275 | case 5: | ||
276 | kf_bfly5(Fout, fstride, st, m); | ||
277 | break; | ||
278 | default: | ||
279 | kf_bfly_generic(Fout, fstride, st, m, p); | ||
280 | break; | ||
301 | } | 281 | } |
282 | return; | ||
283 | } | ||
284 | #endif | ||
285 | |||
286 | if (m == 1) { | ||
287 | do { | ||
288 | *Fout = *f; | ||
289 | f += fstride * in_stride; | ||
290 | } while (++Fout != Fout_end); | ||
291 | } else { | ||
292 | do { | ||
293 | // recursive call: | ||
294 | // DFT of size m*p performed by doing | ||
295 | // p instances of smaller DFTs of size m, | ||
296 | // each one takes a decimated version of the input | ||
297 | kf_work(Fout, f, fstride * p, in_stride, factors, st); | ||
298 | f += fstride * in_stride; | ||
299 | } while ((Fout += m) != Fout_end); | ||
300 | } | ||
301 | |||
302 | Fout = Fout_beg; | ||
303 | |||
304 | // recombine the p smaller DFTs | ||
305 | switch (p) { | ||
306 | case 2: | ||
307 | kf_bfly2(Fout, fstride, st, m); | ||
308 | break; | ||
309 | case 3: | ||
310 | kf_bfly3(Fout, fstride, st, m); | ||
311 | break; | ||
312 | case 4: | ||
313 | kf_bfly4(Fout, fstride, st, m); | ||
314 | break; | ||
315 | case 5: | ||
316 | kf_bfly5(Fout, fstride, st, m); | ||
317 | break; | ||
318 | default: | ||
319 | kf_bfly_generic(Fout, fstride, st, m, p); | ||
320 | break; | ||
321 | } | ||
302 | } | 322 | } |
303 | 323 | ||
304 | /* facbuf is populated by p1,m1,p2,m2, ... | 324 | /* facbuf is populated by p1,m1,p2,m2, ... |
305 | where | 325 | where |
306 | p[i] * m[i] = m[i-1] | 326 | p[i] * m[i] = m[i-1] |
307 | m0 = n */ | 327 | m0 = n */ |
308 | static | 328 | static void kf_factor(int n, int *facbuf) { |
309 | void kf_factor(int n,int * facbuf) | 329 | int p = 4; |
310 | { | 330 | double floor_sqrt; |
311 | int p=4; | 331 | floor_sqrt = floorf(sqrtf((double)n)); |
312 | double floor_sqrt; | 332 | |
313 | floor_sqrt = floorf( sqrtf((double)n) ); | 333 | /*factor out powers of 4, powers of 2, then any remaining primes */ |
314 | 334 | do { | |
315 | /*factor out powers of 4, powers of 2, then any remaining primes */ | 335 | while (n % p) { |
316 | do { | 336 | switch (p) { |
317 | while (n % p) { | 337 | case 4: |
318 | switch (p) { | 338 | p = 2; |
319 | case 4: p = 2; break; | 339 | break; |
320 | case 2: p = 3; break; | 340 | case 2: |
321 | default: p += 2; break; | 341 | p = 3; |
322 | } | 342 | break; |
323 | if (p > floor_sqrt) | 343 | default: |
324 | p = n; /* no more factors, skip to end */ | 344 | p += 2; |
325 | } | 345 | break; |
326 | n /= p; | 346 | } |
327 | *facbuf++ = p; | 347 | if (p > floor_sqrt) p = n; /* no more factors, skip to end */ |
328 | *facbuf++ = n; | 348 | } |
329 | } while (n > 1); | 349 | n /= p; |
350 | *facbuf++ = p; | ||
351 | *facbuf++ = n; | ||
352 | } while (n > 1); | ||
330 | } | 353 | } |
331 | 354 | ||
332 | /* | 355 | /* |
333 | * | 356 | * |
334 | * User-callable function to allocate all necessary storage space for the fft. | 357 | * User-callable function to allocate all necessary storage space for the fft. |
335 | * | 358 | * |
336 | * The return value is a contiguous block of memory, allocated with malloc. As such, | 359 | * The return value is a contiguous block of memory, allocated with malloc. As |
337 | * It can be freed with free(), rather than a kiss_fft-specific function. | 360 | * such, It can be freed with free(), rather than a kiss_fft-specific function. |
338 | * */ | 361 | * */ |
339 | kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) | 362 | kiss_fft_cfg kiss_fft_alloc(int nfft, int inverse_fft, void *mem, |
340 | { | 363 | size_t *lenmem) { |
341 | kiss_fft_cfg st=NULL; | 364 | kiss_fft_cfg st = NULL; |
342 | size_t memneeded = sizeof(struct kiss_fft_state) | 365 | size_t memneeded = sizeof(struct kiss_fft_state) + |
343 | + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ | 366 | sizeof(kiss_fft_cpx) * (nfft - 1); /* twiddle factors*/ |
344 | 367 | ||
345 | if ( lenmem==NULL ) { | 368 | if (lenmem == NULL) { |
346 | st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); | 369 | st = (kiss_fft_cfg)KISS_FFT_MALLOC(memneeded); |
347 | }else{ | 370 | } else { |
348 | if (mem != NULL && *lenmem >= memneeded) | 371 | if (mem != NULL && *lenmem >= memneeded) st = (kiss_fft_cfg)mem; |
349 | st = (kiss_fft_cfg)mem; | 372 | *lenmem = memneeded; |
350 | *lenmem = memneeded; | 373 | } |
351 | } | 374 | if (st) { |
352 | if (st) { | 375 | int i; |
353 | int i; | 376 | st->nfft = nfft; |
354 | st->nfft=nfft; | 377 | st->inverse = inverse_fft; |
355 | st->inverse = inverse_fft; | 378 | |
356 | 379 | for (i = 0; i < nfft; ++i) { | |
357 | for (i=0;i<nfft;++i) { | 380 | const double pi = |
358 | const double pi=3.141592653589793238462643383279502884197169399375105820974944; | 381 | 3.141592653589793238462643383279502884197169399375105820974944; |
359 | double phase = -2*pi*i / nfft; | 382 | double phase = -2 * pi * i / nfft; |
360 | if (st->inverse) | 383 | if (st->inverse) phase *= -1; |
361 | phase *= -1; | 384 | kf_cexp(st->twiddles + i, phase); |
362 | kf_cexp(st->twiddles+i, phase ); | ||
363 | } | ||
364 | |||
365 | kf_factor(nfft,st->factors); | ||
366 | } | 385 | } |
367 | return st; | ||
368 | } | ||
369 | |||
370 | 386 | ||
371 | void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) | 387 | kf_factor(nfft, st->factors); |
372 | { | 388 | } |
373 | if (fin == fout) { | 389 | return st; |
374 | //NOTE: this is not really an in-place FFT algorithm. | ||
375 | //It just performs an out-of-place FFT into a temp buffer | ||
376 | kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); | ||
377 | kf_work(tmpbuf,fin,1,in_stride, st->factors,st); | ||
378 | memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); | ||
379 | KISS_FFT_TMP_FREE(tmpbuf); | ||
380 | }else{ | ||
381 | kf_work( fout, fin, 1,in_stride, st->factors,st ); | ||
382 | } | ||
383 | } | 390 | } |
384 | 391 | ||
385 | void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) | 392 | void kiss_fft_stride(kiss_fft_cfg st, const kiss_fft_cpx *fin, |
386 | { | 393 | kiss_fft_cpx *fout, int in_stride) { |
387 | kiss_fft_stride(cfg,fin,fout,1); | 394 | if (fin == fout) { |
395 | // NOTE: this is not really an in-place FFT algorithm. | ||
396 | // It just performs an out-of-place FFT into a temp buffer | ||
397 | kiss_fft_cpx *tmpbuf = | ||
398 | (kiss_fft_cpx *)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx) * st->nfft); | ||
399 | kf_work(tmpbuf, fin, 1, in_stride, st->factors, st); | ||
400 | memcpy(fout, tmpbuf, sizeof(kiss_fft_cpx) * st->nfft); | ||
401 | KISS_FFT_TMP_FREE(tmpbuf); | ||
402 | } else { | ||
403 | kf_work(fout, fin, 1, in_stride, st->factors, st); | ||
404 | } | ||
388 | } | 405 | } |
389 | 406 | ||
407 | void kiss_fft(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout) { | ||
408 | kiss_fft_stride(cfg, fin, fout, 1); | ||
409 | } | ||
390 | 410 | ||
391 | void kiss_fft_cleanup(void) | 411 | void kiss_fft_cleanup(void) { |
392 | { | 412 | // nothing needed any more |
393 | // nothing needed any more | ||
394 | } | 413 | } |
395 | 414 | ||
396 | int kiss_fft_next_fast_size(int n) | 415 | int kiss_fft_next_fast_size(int n) { |
397 | { | 416 | while (1) { |
398 | while(1) { | 417 | int m = n; |
399 | int m=n; | 418 | while ((m % 2) == 0) m /= 2; |
400 | while ( (m%2) == 0 ) m/=2; | 419 | while ((m % 3) == 0) m /= 3; |
401 | while ( (m%3) == 0 ) m/=3; | 420 | while ((m % 5) == 0) m /= 5; |
402 | while ( (m%5) == 0 ) m/=5; | 421 | if (m <= 1) |
403 | if (m<=1) | 422 | break; /* n is completely factorable by twos, threes, and fives */ |
404 | break; /* n is completely factorable by twos, threes, and fives */ | 423 | n++; |
405 | n++; | 424 | } |
406 | } | 425 | return n; |
407 | return n; | ||
408 | } | 426 | } |
@@ -1,9 +1,9 @@ | |||
1 | #ifndef KISS_FFT_H | 1 | #ifndef KISS_FFT_H |
2 | #define KISS_FFT_H | 2 | #define KISS_FFT_H |
3 | 3 | ||
4 | #include <stdlib.h> | ||
5 | #include <stdio.h> | ||
6 | #include <math.h> | 4 | #include <math.h> |
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | 7 | #include <string.h> |
8 | 8 | ||
9 | #ifdef __cplusplus | 9 | #ifdef __cplusplus |
@@ -24,36 +24,35 @@ extern "C" { | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #ifdef USE_SIMD | 26 | #ifdef USE_SIMD |
27 | # include <xmmintrin.h> | 27 | #include <xmmintrin.h> |
28 | # define kiss_fft_scalar __m128 | 28 | #define kiss_fft_scalar __m128 |
29 | #define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) | 29 | #define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes, 16) |
30 | #define KISS_FFT_FREE _mm_free | 30 | #define KISS_FFT_FREE _mm_free |
31 | #else | 31 | #else |
32 | #define KISS_FFT_MALLOC malloc | 32 | #define KISS_FFT_MALLOC malloc |
33 | #define KISS_FFT_FREE free | 33 | #define KISS_FFT_FREE free |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | |||
37 | #ifdef FIXED_POINT | 36 | #ifdef FIXED_POINT |
38 | #include <sys/types.h> | 37 | #include <sys/types.h> |
39 | # if (FIXED_POINT == 32) | 38 | #if (FIXED_POINT == 32) |
40 | # define kiss_fft_scalar int32_t | 39 | #define kiss_fft_scalar int32_t |
41 | # else | ||
42 | # define kiss_fft_scalar int16_t | ||
43 | # endif | ||
44 | #else | 40 | #else |
45 | # ifndef kiss_fft_scalar | 41 | #define kiss_fft_scalar int16_t |
42 | #endif | ||
43 | #else | ||
44 | #ifndef kiss_fft_scalar | ||
46 | /* default is float */ | 45 | /* default is float */ |
47 | # define kiss_fft_scalar float | 46 | #define kiss_fft_scalar float |
48 | # endif | 47 | #endif |
49 | #endif | 48 | #endif |
50 | 49 | ||
51 | typedef struct { | 50 | typedef struct { |
52 | kiss_fft_scalar r; | 51 | kiss_fft_scalar r; |
53 | kiss_fft_scalar i; | 52 | kiss_fft_scalar i; |
54 | }kiss_fft_cpx; | 53 | } kiss_fft_cpx; |
55 | 54 | ||
56 | typedef struct kiss_fft_state* kiss_fft_cfg; | 55 | typedef struct kiss_fft_state *kiss_fft_cfg; |
57 | 56 | ||
58 | /* | 57 | /* |
59 | * kiss_fft_alloc | 58 | * kiss_fft_alloc |
@@ -65,8 +64,8 @@ typedef struct kiss_fft_state* kiss_fft_cfg; | |||
65 | * The return value from fft_alloc is a cfg buffer used internally | 64 | * The return value from fft_alloc is a cfg buffer used internally |
66 | * by the fft routine or NULL. | 65 | * by the fft routine or NULL. |
67 | * | 66 | * |
68 | * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. | 67 | * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using |
69 | * The returned value should be free()d when done to avoid memory leaks. | 68 | * malloc. The returned value should be free()d when done to avoid memory leaks. |
70 | * | 69 | * |
71 | * The state can be placed in a user supplied buffer 'mem': | 70 | * The state can be placed in a user supplied buffer 'mem': |
72 | * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, | 71 | * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, |
@@ -78,7 +77,8 @@ typedef struct kiss_fft_state* kiss_fft_cfg; | |||
78 | * buffer size in *lenmem. | 77 | * buffer size in *lenmem. |
79 | * */ | 78 | * */ |
80 | 79 | ||
81 | kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); | 80 | kiss_fft_cfg kiss_fft_alloc(int nfft, int inverse_fft, void *mem, |
81 | size_t *lenmem); | ||
82 | 82 | ||
83 | /* | 83 | /* |
84 | * kiss_fft(cfg,in_out_buf) | 84 | * kiss_fft(cfg,in_out_buf) |
@@ -90,32 +90,34 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) | |||
90 | * Note that each element is complex and can be accessed like | 90 | * Note that each element is complex and can be accessed like |
91 | f[k].r and f[k].i | 91 | f[k].r and f[k].i |
92 | * */ | 92 | * */ |
93 | void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); | 93 | void kiss_fft(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout); |
94 | 94 | ||
95 | /* | 95 | /* |
96 | A more generic version of the above function. It reads its input from every Nth sample. | 96 | A more generic version of the above function. It reads its input from every Nth |
97 | sample. | ||
97 | * */ | 98 | * */ |
98 | void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); | 99 | void kiss_fft_stride(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, |
100 | kiss_fft_cpx *fout, int fin_stride); | ||
99 | 101 | ||
100 | /* If kiss_fft_alloc allocated a buffer, it is one contiguous | 102 | /* If kiss_fft_alloc allocated a buffer, it is one contiguous |
101 | buffer and can be simply free()d when no longer needed*/ | 103 | buffer and can be simply free()d when no longer needed*/ |
102 | #define kiss_fft_free free | 104 | #define kiss_fft_free free |
103 | 105 | ||
104 | /* | 106 | /* |
105 | Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up | 107 | Cleans up some memory that gets managed internally. Not necessary to call, but |
106 | your compiler output to call this before you exit. | 108 | it might clean up your compiler output to call this before you exit. |
107 | */ | 109 | */ |
108 | void kiss_fft_cleanup(void); | 110 | void kiss_fft_cleanup(void); |
109 | 111 | ||
110 | |||
111 | /* | 112 | /* |
112 | * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) | 113 | * Returns the smallest integer k, such that k>=n and k has only "fast" factors |
114 | * (2,3,5) | ||
113 | */ | 115 | */ |
114 | int kiss_fft_next_fast_size(int n); | 116 | int kiss_fft_next_fast_size(int n); |
115 | 117 | ||
116 | /* for real ffts, we need an even size */ | 118 | /* for real ffts, we need an even size */ |
117 | #define kiss_fftr_next_fast_size_real(n) \ | 119 | #define kiss_fftr_next_fast_size_real(n) \ |
118 | (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) | 120 | (kiss_fft_next_fast_size(((n) + 1) >> 1) << 1) |
119 | 121 | ||
120 | #ifdef __cplusplus | 122 | #ifdef __cplusplus |
121 | } | 123 | } |
diff --git a/kiss_fftr.c b/kiss_fftr.c index 7cc0286..e3aee37 100644 --- a/kiss_fftr.c +++ b/kiss_fftr.c | |||
@@ -3,152 +3,166 @@ Copyright (c) 2003-2004, Mark Borgerding | |||
3 | 3 | ||
4 | All rights reserved. | 4 | All rights reserved. |
5 | 5 | ||
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | 6 | Redistribution and use in source and binary forms, with or without modification, |
7 | 7 | are permitted provided that the following conditions are met: | |
8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | 8 | |
9 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | 9 | * Redistributions of source code must retain the above copyright notice, |
10 | * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. | 10 | this list of conditions and the following disclaimer. |
11 | 11 | * Redistributions in binary form must reproduce the above copyright notice, | |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 12 | this list of conditions and the following disclaimer in the documentation and/or |
13 | other materials provided with the distribution. | ||
14 | * Neither the author nor the names of any contributors may be used to | ||
15 | endorse or promote products derived from this software without specific prior | ||
16 | written permission. | ||
17 | |||
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
13 | */ | 28 | */ |
14 | 29 | ||
15 | #include "kiss_fftr.h" | 30 | #include "kiss_fftr.h" |
31 | |||
16 | #include "_kiss_fft_guts.h" | 32 | #include "_kiss_fft_guts.h" |
17 | #include "assert.h" | 33 | #include "assert.h" |
18 | 34 | ||
19 | struct kiss_fftr_state{ | 35 | struct kiss_fftr_state { |
20 | kiss_fft_cfg substate; | 36 | kiss_fft_cfg substate; |
21 | kiss_fft_cpx * tmpbuf; | 37 | kiss_fft_cpx *tmpbuf; |
22 | kiss_fft_cpx * super_twiddles; | 38 | kiss_fft_cpx *super_twiddles; |
23 | #ifdef USE_SIMD | 39 | #ifdef USE_SIMD |
24 | void * pad; | 40 | void *pad; |
25 | #endif | 41 | #endif |
26 | }; | 42 | }; |
27 | 43 | ||
28 | kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) | 44 | kiss_fftr_cfg kiss_fftr_alloc(int nfft, int inverse_fft, void *mem, |
29 | { | 45 | size_t *lenmem) { |
30 | int i; | 46 | int i; |
31 | kiss_fftr_cfg st = NULL; | 47 | kiss_fftr_cfg st = NULL; |
32 | size_t subsize, memneeded; | 48 | size_t subsize, memneeded; |
33 | 49 | ||
34 | if (nfft & 1) { | 50 | if (nfft & 1) { |
35 | fprintf(stderr,"Real FFT optimization must be even.\n"); | 51 | fprintf(stderr, "Real FFT optimization must be even.\n"); |
36 | return NULL; | 52 | return NULL; |
37 | } | 53 | } |
38 | nfft >>= 1; | 54 | nfft >>= 1; |
39 | 55 | ||
40 | kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); | 56 | kiss_fft_alloc(nfft, inverse_fft, NULL, &subsize); |
41 | memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); | 57 | memneeded = sizeof(struct kiss_fftr_state) + subsize + |
42 | 58 | sizeof(kiss_fft_cpx) * (nfft * 3 / 2); | |
43 | if (lenmem == NULL) { | 59 | |
44 | st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); | 60 | if (lenmem == NULL) { |
45 | } else { | 61 | st = (kiss_fftr_cfg)KISS_FFT_MALLOC(memneeded); |
46 | if (*lenmem >= memneeded) | 62 | } else { |
47 | st = (kiss_fftr_cfg) mem; | 63 | if (*lenmem >= memneeded) st = (kiss_fftr_cfg)mem; |
48 | *lenmem = memneeded; | 64 | *lenmem = memneeded; |
49 | } | 65 | } |
50 | if (!st) | 66 | if (!st) return NULL; |
51 | return NULL; | 67 | |
52 | 68 | st->substate = (kiss_fft_cfg)(st + 1); /*just beyond kiss_fftr_state struct */ | |
53 | st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ | 69 | st->tmpbuf = (kiss_fft_cpx *)(((char *)st->substate) + subsize); |
54 | st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); | 70 | st->super_twiddles = st->tmpbuf + nfft; |
55 | st->super_twiddles = st->tmpbuf + nfft; | 71 | kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); |
56 | kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); | 72 | |
57 | 73 | for (i = 0; i < nfft / 2; ++i) { | |
58 | for (i = 0; i < nfft/2; ++i) { | 74 | float phase = |
59 | float phase = | 75 | -3.14159265358979323846264338327 * ((float)(i + 1) / nfft + .5); |
60 | -3.14159265358979323846264338327 * ((float) (i+1) / nfft + .5); | 76 | if (inverse_fft) phase *= -1; |
61 | if (inverse_fft) | 77 | kf_cexp(st->super_twiddles + i, phase); |
62 | phase *= -1; | 78 | } |
63 | kf_cexp (st->super_twiddles+i,phase); | 79 | return st; |
64 | } | ||
65 | return st; | ||
66 | } | 80 | } |
67 | 81 | ||
68 | void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) | 82 | void kiss_fftr(kiss_fftr_cfg st, const kiss_fft_scalar *timedata, |
69 | { | 83 | kiss_fft_cpx *freqdata) { |
70 | /* input buffer timedata is stored row-wise */ | 84 | /* input buffer timedata is stored row-wise */ |
71 | int k,ncfft; | 85 | int k, ncfft; |
72 | kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; | 86 | kiss_fft_cpx fpnk, fpk, f1k, f2k, tw, tdc; |
73 | 87 | ||
74 | assert(st->substate->inverse==0); | 88 | assert(st->substate->inverse == 0); |
75 | 89 | ||
76 | ncfft = st->substate->nfft; | 90 | ncfft = st->substate->nfft; |
77 | 91 | ||
78 | /*perform the parallel fft of two real signals packed in real,imag*/ | 92 | /*perform the parallel fft of two real signals packed in real,imag*/ |
79 | kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); | 93 | kiss_fft(st->substate, (const kiss_fft_cpx *)timedata, st->tmpbuf); |
80 | /* The real part of the DC element of the frequency spectrum in st->tmpbuf | 94 | /* The real part of the DC element of the frequency spectrum in st->tmpbuf |
81 | * contains the sum of the even-numbered elements of the input time sequence | 95 | * contains the sum of the even-numbered elements of the input time sequence |
82 | * The imag part is the sum of the odd-numbered elements | 96 | * The imag part is the sum of the odd-numbered elements |
83 | * | 97 | * |
84 | * The sum of tdc.r and tdc.i is the sum of the input time sequence. | 98 | * The sum of tdc.r and tdc.i is the sum of the input time sequence. |
85 | * yielding DC of input time sequence | 99 | * yielding DC of input time sequence |
86 | * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... | 100 | * The difference of tdc.r - tdc.i is the sum of the input (dot product) |
87 | * yielding Nyquist bin of input time sequence | 101 | * [1,-1,1,-1... yielding Nyquist bin of input time sequence |
88 | */ | 102 | */ |
89 | 103 | ||
90 | tdc.r = st->tmpbuf[0].r; | 104 | tdc.r = st->tmpbuf[0].r; |
91 | tdc.i = st->tmpbuf[0].i; | 105 | tdc.i = st->tmpbuf[0].i; |
92 | C_FIXDIV(tdc,2); | 106 | C_FIXDIV(tdc, 2); |
93 | CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); | 107 | CHECK_OVERFLOW_OP(tdc.r, +, tdc.i); |
94 | CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); | 108 | CHECK_OVERFLOW_OP(tdc.r, -, tdc.i); |
95 | freqdata[0].r = tdc.r + tdc.i; | 109 | freqdata[0].r = tdc.r + tdc.i; |
96 | freqdata[ncfft].r = tdc.r - tdc.i; | 110 | freqdata[ncfft].r = tdc.r - tdc.i; |
97 | #ifdef USE_SIMD | 111 | #ifdef USE_SIMD |
98 | freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); | 112 | freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); |
99 | #else | 113 | #else |
100 | freqdata[ncfft].i = freqdata[0].i = 0; | 114 | freqdata[ncfft].i = freqdata[0].i = 0; |
101 | #endif | 115 | #endif |
102 | 116 | ||
103 | for ( k=1;k <= ncfft/2 ; ++k ) { | 117 | for (k = 1; k <= ncfft / 2; ++k) { |
104 | fpk = st->tmpbuf[k]; | 118 | fpk = st->tmpbuf[k]; |
105 | fpnk.r = st->tmpbuf[ncfft-k].r; | 119 | fpnk.r = st->tmpbuf[ncfft - k].r; |
106 | fpnk.i = - st->tmpbuf[ncfft-k].i; | 120 | fpnk.i = -st->tmpbuf[ncfft - k].i; |
107 | C_FIXDIV(fpk,2); | 121 | C_FIXDIV(fpk, 2); |
108 | C_FIXDIV(fpnk,2); | 122 | C_FIXDIV(fpnk, 2); |
109 | 123 | ||
110 | C_ADD( f1k, fpk , fpnk ); | 124 | C_ADD(f1k, fpk, fpnk); |
111 | C_SUB( f2k, fpk , fpnk ); | 125 | C_SUB(f2k, fpk, fpnk); |
112 | C_MUL( tw , f2k , st->super_twiddles[k-1]); | 126 | C_MUL(tw, f2k, st->super_twiddles[k - 1]); |
113 | 127 | ||
114 | freqdata[k].r = HALF_OF(f1k.r + tw.r); | 128 | freqdata[k].r = HALF_OF(f1k.r + tw.r); |
115 | freqdata[k].i = HALF_OF(f1k.i + tw.i); | 129 | freqdata[k].i = HALF_OF(f1k.i + tw.i); |
116 | freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); | 130 | freqdata[ncfft - k].r = HALF_OF(f1k.r - tw.r); |
117 | freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); | 131 | freqdata[ncfft - k].i = HALF_OF(tw.i - f1k.i); |
118 | } | 132 | } |
119 | } | 133 | } |
120 | 134 | ||
121 | void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) | 135 | void kiss_fftri(kiss_fftr_cfg st, const kiss_fft_cpx *freqdata, |
122 | { | 136 | kiss_fft_scalar *timedata) { |
123 | /* input buffer timedata is stored row-wise */ | 137 | /* input buffer timedata is stored row-wise */ |
124 | int k, ncfft; | 138 | int k, ncfft; |
125 | 139 | ||
126 | assert(st->substate->inverse == 1); | 140 | assert(st->substate->inverse == 1); |
127 | 141 | ||
128 | ncfft = st->substate->nfft; | 142 | ncfft = st->substate->nfft; |
129 | 143 | ||
130 | st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; | 144 | st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; |
131 | st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; | 145 | st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; |
132 | C_FIXDIV(st->tmpbuf[0],2); | 146 | C_FIXDIV(st->tmpbuf[0], 2); |
133 | 147 | ||
134 | for (k = 1; k <= ncfft / 2; ++k) { | 148 | for (k = 1; k <= ncfft / 2; ++k) { |
135 | kiss_fft_cpx fk, fnkc, fek, fok, tmp; | 149 | kiss_fft_cpx fk, fnkc, fek, fok, tmp; |
136 | fk = freqdata[k]; | 150 | fk = freqdata[k]; |
137 | fnkc.r = freqdata[ncfft - k].r; | 151 | fnkc.r = freqdata[ncfft - k].r; |
138 | fnkc.i = -freqdata[ncfft - k].i; | 152 | fnkc.i = -freqdata[ncfft - k].i; |
139 | C_FIXDIV( fk , 2 ); | 153 | C_FIXDIV(fk, 2); |
140 | C_FIXDIV( fnkc , 2 ); | 154 | C_FIXDIV(fnkc, 2); |
141 | 155 | ||
142 | C_ADD (fek, fk, fnkc); | 156 | C_ADD(fek, fk, fnkc); |
143 | C_SUB (tmp, fk, fnkc); | 157 | C_SUB(tmp, fk, fnkc); |
144 | C_MUL (fok, tmp, st->super_twiddles[k-1]); | 158 | C_MUL(fok, tmp, st->super_twiddles[k - 1]); |
145 | C_ADD (st->tmpbuf[k], fek, fok); | 159 | C_ADD(st->tmpbuf[k], fek, fok); |
146 | C_SUB (st->tmpbuf[ncfft - k], fek, fok); | 160 | C_SUB(st->tmpbuf[ncfft - k], fek, fok); |
147 | #ifdef USE_SIMD | 161 | #ifdef USE_SIMD |
148 | st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); | 162 | st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); |
149 | #else | 163 | #else |
150 | st->tmpbuf[ncfft - k].i *= -1; | 164 | st->tmpbuf[ncfft - k].i *= -1; |
151 | #endif | 165 | #endif |
152 | } | 166 | } |
153 | kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); | 167 | kiss_fft(st->substate, st->tmpbuf, (kiss_fft_cpx *)timedata); |
154 | } | 168 | } |
diff --git a/kiss_fftr.h b/kiss_fftr.h index 72e5a57..4ab52db 100644 --- a/kiss_fftr.h +++ b/kiss_fftr.h | |||
@@ -6,33 +6,34 @@ | |||
6 | extern "C" { | 6 | extern "C" { |
7 | #endif | 7 | #endif |
8 | 8 | ||
9 | 9 | /* | |
10 | /* | 10 | |
11 | 11 | Real optimized version can save about 45% cpu time vs. complex fft of a real | |
12 | Real optimized version can save about 45% cpu time vs. complex fft of a real seq. | 12 | seq. |
13 | |||
14 | |||
13 | 15 | ||
14 | |||
15 | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | typedef struct kiss_fftr_state *kiss_fftr_cfg; | 18 | typedef struct kiss_fftr_state *kiss_fftr_cfg; |
19 | 19 | ||
20 | 20 | kiss_fftr_cfg kiss_fftr_alloc(int nfft, int inverse_fft, void *mem, | |
21 | kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); | 21 | size_t *lenmem); |
22 | /* | 22 | /* |
23 | nfft must be even | 23 | nfft must be even |
24 | 24 | ||
25 | If you don't care to allocate space, use mem = lenmem = NULL | 25 | If you don't care to allocate space, use mem = lenmem = NULL |
26 | */ | 26 | */ |
27 | 27 | ||
28 | 28 | void kiss_fftr(kiss_fftr_cfg cfg, const kiss_fft_scalar *timedata, | |
29 | void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); | 29 | kiss_fft_cpx *freqdata); |
30 | /* | 30 | /* |
31 | input timedata has nfft scalar points | 31 | input timedata has nfft scalar points |
32 | output freqdata has nfft/2+1 complex points | 32 | output freqdata has nfft/2+1 complex points |
33 | */ | 33 | */ |
34 | 34 | ||
35 | void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); | 35 | void kiss_fftri(kiss_fftr_cfg cfg, const kiss_fft_cpx *freqdata, |
36 | kiss_fft_scalar *timedata); | ||
36 | /* | 37 | /* |
37 | input freqdata has nfft/2+1 complex points | 38 | input freqdata has nfft/2+1 complex points |
38 | output timedata has nfft scalar points | 39 | output timedata has nfft scalar points |
@@ -25,16 +25,18 @@ | |||
25 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 25 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #define LPC_MAX_N 512 /* maximum no. of samples in frame */ | 28 | #define LPC_MAX_N 512 /* maximum no. of samples in frame */ |
29 | #define PI 3.141592654 /* mathematical constant */ | 29 | #define PI 3.141592654 /* mathematical constant */ |
30 | 30 | ||
31 | #define ALPHA 1.0 | 31 | #define ALPHA 1.0 |
32 | #define BETA 0.94 | 32 | #define BETA 0.94 |
33 | |||
34 | #include "lpc.h" | ||
33 | 35 | ||
34 | #include <assert.h> | 36 | #include <assert.h> |
35 | #include <math.h> | 37 | #include <math.h> |
38 | |||
36 | #include "defines.h" | 39 | #include "defines.h" |
37 | #include "lpc.h" | ||
38 | 40 | ||
39 | /*---------------------------------------------------------------------------*\ | 41 | /*---------------------------------------------------------------------------*\ |
40 | 42 | ||
@@ -42,29 +44,25 @@ | |||
42 | 44 | ||
43 | Pre-emphasise (high pass filter with zero close to 0 Hz) a frame of | 45 | Pre-emphasise (high pass filter with zero close to 0 Hz) a frame of |
44 | speech samples. Helps reduce dynamic range of LPC spectrum, giving | 46 | speech samples. Helps reduce dynamic range of LPC spectrum, giving |
45 | greater weight and hense a better match to low energy formants. | 47 | greater weight and hence a better match to low energy formants. |
46 | 48 | ||
47 | Should be balanced by de-emphasis of the output speech. | 49 | Should be balanced by de-emphasis of the output speech. |
48 | 50 | ||
49 | \*---------------------------------------------------------------------------*/ | 51 | \*---------------------------------------------------------------------------*/ |
50 | 52 | ||
51 | void pre_emp( | 53 | void pre_emp(float Sn_pre[], /* output frame of speech samples */ |
52 | float Sn_pre[], /* output frame of speech samples */ | 54 | float Sn[], /* input frame of speech samples */ |
53 | float Sn[], /* input frame of speech samples */ | 55 | float *mem, /* Sn[-1]single sample memory */ |
54 | float *mem, /* Sn[-1]single sample memory */ | 56 | int Nsam /* number of speech samples to use */ |
55 | int Nsam /* number of speech samples to use */ | 57 | ) { |
56 | ) | 58 | int i; |
57 | { | ||
58 | int i; | ||
59 | |||
60 | for(i=0; i<Nsam; i++) { | ||
61 | Sn_pre[i] = Sn[i] - ALPHA * mem[0]; | ||
62 | mem[0] = Sn[i]; | ||
63 | } | ||
64 | 59 | ||
60 | for (i = 0; i < Nsam; i++) { | ||
61 | Sn_pre[i] = Sn[i] - ALPHA * mem[0]; | ||
62 | mem[0] = Sn[i]; | ||
63 | } | ||
65 | } | 64 | } |
66 | 65 | ||
67 | |||
68 | /*---------------------------------------------------------------------------*\ | 66 | /*---------------------------------------------------------------------------*\ |
69 | 67 | ||
70 | de_emp() | 68 | de_emp() |
@@ -73,23 +71,19 @@ void pre_emp( | |||
73 | 71 | ||
74 | \*---------------------------------------------------------------------------*/ | 72 | \*---------------------------------------------------------------------------*/ |
75 | 73 | ||
76 | void de_emp( | 74 | void de_emp(float Sn_de[], /* output frame of speech samples */ |
77 | float Sn_de[], /* output frame of speech samples */ | 75 | float Sn[], /* input frame of speech samples */ |
78 | float Sn[], /* input frame of speech samples */ | 76 | float *mem, /* Sn[-1]single sample memory */ |
79 | float *mem, /* Sn[-1]single sample memory */ | 77 | int Nsam /* number of speech samples to use */ |
80 | int Nsam /* number of speech samples to use */ | 78 | ) { |
81 | ) | 79 | int i; |
82 | { | ||
83 | int i; | ||
84 | |||
85 | for(i=0; i<Nsam; i++) { | ||
86 | Sn_de[i] = Sn[i] + BETA * mem[0]; | ||
87 | mem[0] = Sn_de[i]; | ||
88 | } | ||
89 | 80 | ||
81 | for (i = 0; i < Nsam; i++) { | ||
82 | Sn_de[i] = Sn[i] + BETA * mem[0]; | ||
83 | mem[0] = Sn_de[i]; | ||
84 | } | ||
90 | } | 85 | } |
91 | 86 | ||
92 | |||
93 | /*---------------------------------------------------------------------------*\ | 87 | /*---------------------------------------------------------------------------*\ |
94 | 88 | ||
95 | hanning_window() | 89 | hanning_window() |
@@ -98,16 +92,14 @@ void de_emp( | |||
98 | 92 | ||
99 | \*---------------------------------------------------------------------------*/ | 93 | \*---------------------------------------------------------------------------*/ |
100 | 94 | ||
101 | void hanning_window( | 95 | void hanning_window(float Sn[], /* input frame of speech samples */ |
102 | float Sn[], /* input frame of speech samples */ | 96 | float Wn[], /* output frame of windowed samples */ |
103 | float Wn[], /* output frame of windowed samples */ | 97 | int Nsam /* number of samples */ |
104 | int Nsam /* number of samples */ | 98 | ) { |
105 | ) | 99 | int i; /* loop variable */ |
106 | { | ||
107 | int i; /* loop variable */ | ||
108 | 100 | ||
109 | for(i=0; i<Nsam; i++) | 101 | for (i = 0; i < Nsam; i++) |
110 | Wn[i] = Sn[i]*(0.5 - 0.5*cosf(2*PI*(float)i/(Nsam-1))); | 102 | Wn[i] = Sn[i] * (0.5 - 0.5 * cosf(2 * PI * (float)i / (Nsam - 1))); |
111 | } | 103 | } |
112 | 104 | ||
113 | /*---------------------------------------------------------------------------*\ | 105 | /*---------------------------------------------------------------------------*\ |
@@ -119,19 +111,16 @@ void hanning_window( | |||
119 | 111 | ||
120 | \*---------------------------------------------------------------------------*/ | 112 | \*---------------------------------------------------------------------------*/ |
121 | 113 | ||
122 | void autocorrelate( | 114 | void autocorrelate(float Sn[], /* frame of Nsam windowed speech samples */ |
123 | float Sn[], /* frame of Nsam windowed speech samples */ | 115 | float Rn[], /* array of P+1 autocorrelation coefficients */ |
124 | float Rn[], /* array of P+1 autocorrelation coefficients */ | 116 | int Nsam, /* number of windowed samples to use */ |
125 | int Nsam, /* number of windowed samples to use */ | 117 | int order /* order of LPC analysis */ |
126 | int order /* order of LPC analysis */ | 118 | ) { |
127 | ) | 119 | int i, j; /* loop variables */ |
128 | { | ||
129 | int i,j; /* loop variables */ | ||
130 | 120 | ||
131 | for(j=0; j<order+1; j++) { | 121 | for (j = 0; j < order + 1; j++) { |
132 | Rn[j] = 0.0; | 122 | Rn[j] = 0.0; |
133 | for(i=0; i<Nsam-j; i++) | 123 | for (i = 0; i < Nsam - j; i++) Rn[j] += Sn[i] * Sn[i + j]; |
134 | Rn[j] += Sn[i]*Sn[i+j]; | ||
135 | } | 124 | } |
136 | } | 125 | } |
137 | 126 | ||
@@ -150,36 +139,31 @@ void autocorrelate( | |||
150 | 139 | ||
151 | \*---------------------------------------------------------------------------*/ | 140 | \*---------------------------------------------------------------------------*/ |
152 | 141 | ||
153 | void levinson_durbin( | 142 | void levinson_durbin(float R[], /* order+1 autocorrelation coeff */ |
154 | float R[], /* order+1 autocorrelation coeff */ | 143 | float lpcs[], /* order+1 LPC's */ |
155 | float lpcs[], /* order+1 LPC's */ | 144 | int order /* order of the LPC analysis */ |
156 | int order /* order of the LPC analysis */ | 145 | ) { |
157 | ) | 146 | float a[order + 1][order + 1]; |
158 | { | ||
159 | float a[order+1][order+1]; | ||
160 | float sum, e, k; | 147 | float sum, e, k; |
161 | int i,j; /* loop variables */ | 148 | int i, j; /* loop variables */ |
162 | 149 | ||
163 | e = R[0]; /* Equation 38a, Makhoul */ | 150 | e = R[0]; /* Equation 38a, Makhoul */ |
164 | 151 | ||
165 | for(i=1; i<=order; i++) { | 152 | for (i = 1; i <= order; i++) { |
166 | sum = 0.0; | 153 | sum = 0.0; |
167 | for(j=1; j<=i-1; j++) | 154 | for (j = 1; j <= i - 1; j++) sum += a[i - 1][j] * R[i - j]; |
168 | sum += a[i-1][j]*R[i-j]; | 155 | k = -1.0 * (R[i] + sum) / e; /* Equation 38b, Makhoul */ |
169 | k = -1.0*(R[i] + sum)/e; /* Equation 38b, Makhoul */ | 156 | if (fabsf(k) > 1.0) k = 0.0; |
170 | if (fabsf(k) > 1.0) | ||
171 | k = 0.0; | ||
172 | 157 | ||
173 | a[i][i] = k; | 158 | a[i][i] = k; |
174 | 159 | ||
175 | for(j=1; j<=i-1; j++) | 160 | for (j = 1; j <= i - 1; j++) |
176 | a[i][j] = a[i-1][j] + k*a[i-1][i-j]; /* Equation 38c, Makhoul */ | 161 | a[i][j] = a[i - 1][j] + k * a[i - 1][i - j]; /* Equation 38c, Makhoul */ |
177 | 162 | ||
178 | e *= (1-k*k); /* Equation 38d, Makhoul */ | 163 | e *= (1 - k * k); /* Equation 38d, Makhoul */ |
179 | } | 164 | } |
180 | 165 | ||
181 | for(i=1; i<=order; i++) | 166 | for (i = 1; i <= order; i++) lpcs[i] = a[order][i]; |
182 | lpcs[i] = a[order][i]; | ||
183 | lpcs[0] = 1.0; | 167 | lpcs[0] = 1.0; |
184 | } | 168 | } |
185 | 169 | ||
@@ -194,20 +178,17 @@ void levinson_durbin( | |||
194 | 178 | ||
195 | \*---------------------------------------------------------------------------*/ | 179 | \*---------------------------------------------------------------------------*/ |
196 | 180 | ||
197 | void inverse_filter( | 181 | void inverse_filter(float Sn[], /* Nsam input samples */ |
198 | float Sn[], /* Nsam input samples */ | 182 | float a[], /* LPCs for this frame of samples */ |
199 | float a[], /* LPCs for this frame of samples */ | 183 | int Nsam, /* number of samples */ |
200 | int Nsam, /* number of samples */ | 184 | float res[], /* Nsam residual samples */ |
201 | float res[], /* Nsam residual samples */ | 185 | int order /* order of LPC */ |
202 | int order /* order of LPC */ | 186 | ) { |
203 | ) | 187 | int i, j; /* loop variables */ |
204 | { | 188 | |
205 | int i,j; /* loop variables */ | 189 | for (i = 0; i < Nsam; i++) { |
206 | |||
207 | for(i=0; i<Nsam; i++) { | ||
208 | res[i] = 0.0; | 190 | res[i] = 0.0; |
209 | for(j=0; j<=order; j++) | 191 | for (j = 0; j <= order; j++) res[i] += Sn[i - j] * a[j]; |
210 | res[i] += Sn[i-j]*a[j]; | ||
211 | } | 192 | } |
212 | } | 193 | } |
213 | 194 | ||
@@ -223,7 +204,7 @@ void inverse_filter( | |||
223 | The synthesis filter has memory as well, this is treated in the same way | 204 | The synthesis filter has memory as well, this is treated in the same way |
224 | as the memory for the inverse filter (see inverse_filter() notes above). | 205 | as the memory for the inverse filter (see inverse_filter() notes above). |
225 | The difference is that the memory for the synthesis filter is stored in | 206 | The difference is that the memory for the synthesis filter is stored in |
226 | the output array, wheras the memory of the inverse filter is stored in the | 207 | the output array, whereas the memory of the inverse filter is stored in the |
227 | input array. | 208 | input array. |
228 | 209 | ||
229 | Note: the calling function must update the filter memory. | 210 | Note: the calling function must update the filter memory. |
@@ -231,21 +212,19 @@ void inverse_filter( | |||
231 | \*---------------------------------------------------------------------------*/ | 212 | \*---------------------------------------------------------------------------*/ |
232 | 213 | ||
233 | void synthesis_filter( | 214 | void synthesis_filter( |
234 | float res[], /* Nsam input residual (excitation) samples */ | 215 | float res[], /* Nsam input residual (excitation) samples */ |
235 | float a[], /* LPCs for this frame of speech samples */ | 216 | float a[], /* LPCs for this frame of speech samples */ |
236 | int Nsam, /* number of speech samples */ | 217 | int Nsam, /* number of speech samples */ |
237 | int order, /* LPC order */ | 218 | int order, /* LPC order */ |
238 | float Sn_[] /* Nsam output synthesised speech samples */ | 219 | float Sn_[] /* Nsam output synthesised speech samples */ |
239 | ) | 220 | ) { |
240 | { | 221 | int i, j; /* loop variables */ |
241 | int i,j; /* loop variables */ | ||
242 | 222 | ||
243 | /* Filter Nsam samples */ | 223 | /* Filter Nsam samples */ |
244 | 224 | ||
245 | for(i=0; i<Nsam; i++) { | 225 | for (i = 0; i < Nsam; i++) { |
246 | Sn_[i] = res[i]*a[0]; | 226 | Sn_[i] = res[i] * a[0]; |
247 | for(j=1; j<=order; j++) | 227 | for (j = 1; j <= order; j++) Sn_[i] -= Sn_[i - j] * a[j]; |
248 | Sn_[i] -= Sn_[i-j]*a[j]; | ||
249 | } | 228 | } |
250 | } | 229 | } |
251 | 230 | ||
@@ -258,29 +237,25 @@ void synthesis_filter( | |||
258 | 237 | ||
259 | \*---------------------------------------------------------------------------*/ | 238 | \*---------------------------------------------------------------------------*/ |
260 | 239 | ||
261 | void find_aks( | 240 | void find_aks(float Sn[], /* Nsam samples with order sample memory */ |
262 | float Sn[], /* Nsam samples with order sample memory */ | 241 | float a[], /* order+1 LPCs with first coeff 1.0 */ |
263 | float a[], /* order+1 LPCs with first coeff 1.0 */ | 242 | int Nsam, /* number of input speech samples */ |
264 | int Nsam, /* number of input speech samples */ | 243 | int order, /* order of the LPC analysis */ |
265 | int order, /* order of the LPC analysis */ | 244 | float *E /* residual energy */ |
266 | float *E /* residual energy */ | 245 | ) { |
267 | ) | 246 | float Wn[LPC_MAX_N]; /* windowed frame of Nsam speech samples */ |
268 | { | 247 | float R[order + 1]; /* order+1 autocorrelation values of Sn[] */ |
269 | float Wn[LPC_MAX_N]; /* windowed frame of Nsam speech samples */ | ||
270 | float R[order+1]; /* order+1 autocorrelation values of Sn[] */ | ||
271 | int i; | 248 | int i; |
272 | 249 | ||
273 | assert(Nsam < LPC_MAX_N); | 250 | assert(Nsam < LPC_MAX_N); |
274 | 251 | ||
275 | hanning_window(Sn,Wn,Nsam); | 252 | hanning_window(Sn, Wn, Nsam); |
276 | autocorrelate(Wn,R,Nsam,order); | 253 | autocorrelate(Wn, R, Nsam, order); |
277 | levinson_durbin(R,a,order); | 254 | levinson_durbin(R, a, order); |
278 | 255 | ||
279 | *E = 0.0; | 256 | *E = 0.0; |
280 | for(i=0; i<=order; i++) | 257 | for (i = 0; i <= order; i++) *E += a[i] * R[i]; |
281 | *E += a[i]*R[i]; | 258 | if (*E < 0.0) *E = 1E-12; |
282 | if (*E < 0.0) | ||
283 | *E = 1E-12; | ||
284 | } | 259 | } |
285 | 260 | ||
286 | /*---------------------------------------------------------------------------*\ | 261 | /*---------------------------------------------------------------------------*\ |
@@ -291,16 +266,12 @@ void find_aks( | |||
291 | 266 | ||
292 | \*---------------------------------------------------------------------------*/ | 267 | \*---------------------------------------------------------------------------*/ |
293 | 268 | ||
294 | void weight( | 269 | void weight(float ak[], /* vector of order+1 LPCs */ |
295 | float ak[], /* vector of order+1 LPCs */ | 270 | float gamma, /* weighting factor */ |
296 | float gamma, /* weighting factor */ | 271 | int order, /* num LPCs (excluding leading 1.0) */ |
297 | int order, /* num LPCs (excluding leading 1.0) */ | 272 | float akw[] /* weighted vector of order+1 LPCs */ |
298 | float akw[] /* weighted vector of order+1 LPCs */ | 273 | ) { |
299 | ) | ||
300 | { | ||
301 | int i; | 274 | int i; |
302 | 275 | ||
303 | for(i=1; i<=order; i++) | 276 | for (i = 1; i <= order; i++) akw[i] = ak[i] * powf(gamma, (float)i); |
304 | akw[i] = ak[i]*powf(gamma,(float)i); | ||
305 | } | 277 | } |
306 | |||
@@ -32,12 +32,12 @@ | |||
32 | 32 | ||
33 | void pre_emp(float Sn_pre[], float Sn[], float *mem, int Nsam); | 33 | void pre_emp(float Sn_pre[], float Sn[], float *mem, int Nsam); |
34 | void de_emp(float Sn_se[], float Sn[], float *mem, int Nsam); | 34 | void de_emp(float Sn_se[], float Sn[], float *mem, int Nsam); |
35 | void hanning_window(float Sn[], float Wn[], int Nsam); | 35 | void hanning_window(float Sn[], float Wn[], int Nsam); |
36 | void autocorrelate(float Sn[], float Rn[], int Nsam, int order); | 36 | void autocorrelate(float Sn[], float Rn[], int Nsam, int order); |
37 | void levinson_durbin(float R[], float lpcs[], int order); | 37 | void levinson_durbin(float R[], float lpcs[], int order); |
38 | void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order); | 38 | void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order); |
39 | void synthesis_filter(float res[], float a[], int Nsam, int order, float Sn_[]); | 39 | void synthesis_filter(float res[], float a[], int Nsam, int order, float Sn_[]); |
40 | void find_aks(float Sn[], float a[], int Nsam, int order, float *E); | 40 | void find_aks(float Sn[], float a[], int Nsam, int order, float *E); |
41 | void weight(float ak[], float gamma, int order, float akw[]); | 41 | void weight(float ak[], float gamma, int order, float akw[]); |
42 | 42 | ||
43 | #endif | 43 | #endif |
@@ -28,12 +28,14 @@ | |||
28 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 28 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "defines.h" | ||
32 | #include "lsp.h" | 31 | #include "lsp.h" |
32 | |||
33 | #include <math.h> | 33 | #include <math.h> |
34 | #include <stdio.h> | 34 | #include <stdio.h> |
35 | #include <stdlib.h> | 35 | #include <stdlib.h> |
36 | 36 | ||
37 | #include "defines.h" | ||
38 | |||
37 | /*---------------------------------------------------------------------------*\ | 39 | /*---------------------------------------------------------------------------*\ |
38 | 40 | ||
39 | Introduction to Line Spectrum Pairs (LSPs) | 41 | Introduction to Line Spectrum Pairs (LSPs) |
@@ -77,49 +79,45 @@ | |||
77 | AUTHOR......: David Rowe | 79 | AUTHOR......: David Rowe |
78 | DATE CREATED: 24/2/93 | 80 | DATE CREATED: 24/2/93 |
79 | 81 | ||
80 | This function evalutes a series of chebyshev polynomials | 82 | This function evaluates a series of chebyshev polynomials |
81 | 83 | ||
82 | FIXME: performing memory allocation at run time is very inefficient, | 84 | FIXME: performing memory allocation at run time is very inefficient, |
83 | replace with stack variables of MAX_P size. | 85 | replace with stack variables of MAX_P size. |
84 | 86 | ||
85 | \*---------------------------------------------------------------------------*/ | 87 | \*---------------------------------------------------------------------------*/ |
86 | 88 | ||
87 | 89 | static float cheb_poly_eva(float *coef, float x, int order) | |
88 | static float | ||
89 | cheb_poly_eva(float *coef,float x,int order) | ||
90 | /* float coef[] coefficients of the polynomial to be evaluated */ | 90 | /* float coef[] coefficients of the polynomial to be evaluated */ |
91 | /* float x the point where polynomial is to be evaluated */ | 91 | /* float x the point where polynomial is to be evaluated */ |
92 | /* int order order of the polynomial */ | 92 | /* int order order of the polynomial */ |
93 | { | 93 | { |
94 | int i; | 94 | int i; |
95 | float *t,*u,*v,sum; | 95 | float *t, *u, *v, sum; |
96 | float T[(order / 2) + 1]; | 96 | float T[(order / 2) + 1]; |
97 | 97 | ||
98 | /* Initialise pointers */ | 98 | /* Initialise pointers */ |
99 | 99 | ||
100 | t = T; /* T[i-2] */ | 100 | t = T; /* T[i-2] */ |
101 | *t++ = 1.0; | 101 | *t++ = 1.0; |
102 | u = t--; /* T[i-1] */ | 102 | u = t--; /* T[i-1] */ |
103 | *u++ = x; | 103 | *u++ = x; |
104 | v = u--; /* T[i] */ | 104 | v = u--; /* T[i] */ |
105 | 105 | ||
106 | /* Evaluate chebyshev series formulation using iterative approach */ | 106 | /* Evaluate chebyshev series formulation using iterative approach */ |
107 | 107 | ||
108 | for(i=2;i<=order/2;i++) | 108 | for (i = 2; i <= order / 2; i++) |
109 | *v++ = (2*x)*(*u++) - *t++; /* T[i] = 2*x*T[i-1] - T[i-2] */ | 109 | *v++ = (2 * x) * (*u++) - *t++; /* T[i] = 2*x*T[i-1] - T[i-2] */ |
110 | 110 | ||
111 | sum=0.0; /* initialise sum to zero */ | 111 | sum = 0.0; /* initialise sum to zero */ |
112 | t = T; /* reset pointer */ | 112 | t = T; /* reset pointer */ |
113 | 113 | ||
114 | /* Evaluate polynomial and return value also free memory space */ | 114 | /* Evaluate polynomial and return value also free memory space */ |
115 | 115 | ||
116 | for(i=0;i<=order/2;i++) | 116 | for (i = 0; i <= order / 2; i++) sum += coef[(order / 2) - i] * *t++; |
117 | sum+=coef[(order/2)-i]**t++; | ||
118 | 117 | ||
119 | return sum; | 118 | return sum; |
120 | } | 119 | } |
121 | 120 | ||
122 | |||
123 | /*---------------------------------------------------------------------------*\ | 121 | /*---------------------------------------------------------------------------*\ |
124 | 122 | ||
125 | FUNCTION....: lpc_to_lsp() | 123 | FUNCTION....: lpc_to_lsp() |
@@ -130,121 +128,118 @@ cheb_poly_eva(float *coef,float x,int order) | |||
130 | 128 | ||
131 | \*---------------------------------------------------------------------------*/ | 129 | \*---------------------------------------------------------------------------*/ |
132 | 130 | ||
133 | int lpc_to_lsp (float *a, int order, float *freq, int nb, float delta) | 131 | int lpc_to_lsp(float *a, int order, float *freq, int nb, float delta) |
134 | /* float *a lpc coefficients */ | 132 | /* float *a lpc coefficients */ |
135 | /* int order order of LPC coefficients (10) */ | 133 | /* int order order of LPC coefficients (10) */ |
136 | /* float *freq LSP frequencies in radians */ | 134 | /* float *freq LSP frequencies in radians */ |
137 | /* int nb number of sub-intervals (4) */ | 135 | /* int nb number of sub-intervals (4) */ |
138 | /* float delta grid spacing interval (0.02) */ | 136 | /* float delta grid spacing interval (0.02) */ |
139 | { | 137 | { |
140 | float psuml,psumr,psumm,temp_xr,xl,xr,xm = 0; | 138 | float psuml, psumr, psumm, temp_xr, xl, xr, xm = 0; |
141 | float temp_psumr; | 139 | float temp_psumr; |
142 | int i,j,m,flag,k; | 140 | int i, j, m, flag, k; |
143 | float *px; /* ptrs of respective P'(z) & Q'(z) */ | 141 | float *px; /* ptrs of respective P'(z) & Q'(z) */ |
144 | float *qx; | 142 | float *qx; |
145 | float *p; | 143 | float *p; |
146 | float *q; | 144 | float *q; |
147 | float *pt; /* ptr used for cheb_poly_eval() | 145 | float *pt; /* ptr used for cheb_poly_eval() |
148 | whether P' or Q' */ | 146 | whether P' or Q' */ |
149 | int roots=0; /* number of roots found */ | 147 | int roots = 0; /* number of roots found */ |
150 | float Q[order + 1]; | 148 | float Q[order + 1]; |
151 | float P[order + 1]; | 149 | float P[order + 1]; |
152 | 150 | ||
151 | flag = 1; | ||
152 | m = order / 2; /* order of P'(z) & Q'(z) polynimials */ | ||
153 | |||
154 | /* Allocate memory space for polynomials */ | ||
155 | |||
156 | /* determine P'(z)'s and Q'(z)'s coefficients where | ||
157 | P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ | ||
158 | |||
159 | px = P; /* initilaise ptrs */ | ||
160 | qx = Q; | ||
161 | p = px; | ||
162 | q = qx; | ||
163 | *px++ = 1.0; | ||
164 | *qx++ = 1.0; | ||
165 | for (i = 1; i <= m; i++) { | ||
166 | *px++ = a[i] + a[order + 1 - i] - *p++; | ||
167 | *qx++ = a[i] - a[order + 1 - i] + *q++; | ||
168 | } | ||
169 | px = P; | ||
170 | qx = Q; | ||
171 | for (i = 0; i < m; i++) { | ||
172 | *px = 2 * *px; | ||
173 | *qx = 2 * *qx; | ||
174 | px++; | ||
175 | qx++; | ||
176 | } | ||
177 | px = P; /* re-initialise ptrs */ | ||
178 | qx = Q; | ||
179 | |||
180 | /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). | ||
181 | Keep alternating between the two polynomials as each zero is found */ | ||
182 | |||
183 | xr = 0; /* initialise xr to zero */ | ||
184 | xl = 1.0; /* start at point xl = 1 */ | ||
185 | |||
186 | for (j = 0; j < order; j++) { | ||
187 | if (j % 2) /* determines whether P' or Q' is eval. */ | ||
188 | pt = qx; | ||
189 | else | ||
190 | pt = px; | ||
191 | |||
192 | psuml = cheb_poly_eva(pt, xl, order); /* evals poly. at xl */ | ||
153 | flag = 1; | 193 | flag = 1; |
154 | m = order/2; /* order of P'(z) & Q'(z) polynimials */ | 194 | while (flag && (xr >= -1.0)) { |
155 | 195 | xr = xl - delta; /* interval spacing */ | |
156 | /* Allocate memory space for polynomials */ | 196 | psumr = cheb_poly_eva(pt, xr, order); /* poly(xl-delta_x) */ |
157 | 197 | temp_psumr = psumr; | |
158 | /* determine P'(z)'s and Q'(z)'s coefficients where | 198 | temp_xr = xr; |
159 | P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ | 199 | |
160 | 200 | /* if no sign change increment xr and re-evaluate | |
161 | px = P; /* initilaise ptrs */ | 201 | poly(xr). Repeat til sign change. if a sign change has |
162 | qx = Q; | 202 | occurred the interval is bisected and then checked again |
163 | p = px; | 203 | for a sign change which determines in which interval the |
164 | q = qx; | 204 | zero lies in. If there is no sign change between poly(xm) |
165 | *px++ = 1.0; | 205 | and poly(xl) set interval between xm and xr else set |
166 | *qx++ = 1.0; | 206 | interval between xl and xr and repeat till root is located |
167 | for(i=1;i<=m;i++){ | 207 | within the specified limits */ |
168 | *px++ = a[i]+a[order+1-i]-*p++; | 208 | |
169 | *qx++ = a[i]-a[order+1-i]+*q++; | 209 | if (((psumr * psuml) < 0.0) || (psumr == 0.0)) { |
170 | } | 210 | roots++; |
171 | px = P; | 211 | |
172 | qx = Q; | 212 | psumm = psuml; |
173 | for(i=0;i<m;i++){ | 213 | for (k = 0; k <= nb; k++) { |
174 | *px = 2**px; | 214 | xm = (xl + xr) / 2; /* bisect the interval */ |
175 | *qx = 2**qx; | 215 | psumm = cheb_poly_eva(pt, xm, order); |
176 | px++; | 216 | if (psumm * psuml > 0.) { |
177 | qx++; | 217 | psuml = psumm; |
178 | } | 218 | xl = xm; |
179 | px = P; /* re-initialise ptrs */ | 219 | } else { |
180 | qx = Q; | 220 | psumr = psumm; |
181 | 221 | xr = xm; | |
182 | /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). | 222 | } |
183 | Keep alternating between the two polynomials as each zero is found */ | 223 | } |
184 | 224 | ||
185 | xr = 0; /* initialise xr to zero */ | 225 | /* once zero is found, reset initial interval to xr */ |
186 | xl = 1.0; /* start at point xl = 1 */ | 226 | freq[j] = (xm); |
187 | 227 | xl = xm; | |
188 | 228 | flag = 0; /* reset flag for next search */ | |
189 | for(j=0;j<order;j++){ | 229 | } else { |
190 | if(j%2) /* determines whether P' or Q' is eval. */ | 230 | psuml = temp_psumr; |
191 | pt = qx; | 231 | xl = temp_xr; |
192 | else | 232 | } |
193 | pt = px; | ||
194 | |||
195 | psuml = cheb_poly_eva(pt,xl,order); /* evals poly. at xl */ | ||
196 | flag = 1; | ||
197 | while(flag && (xr >= -1.0)){ | ||
198 | xr = xl - delta ; /* interval spacing */ | ||
199 | psumr = cheb_poly_eva(pt,xr,order);/* poly(xl-delta_x) */ | ||
200 | temp_psumr = psumr; | ||
201 | temp_xr = xr; | ||
202 | |||
203 | /* if no sign change increment xr and re-evaluate | ||
204 | poly(xr). Repeat til sign change. if a sign change has | ||
205 | occurred the interval is bisected and then checked again | ||
206 | for a sign change which determines in which interval the | ||
207 | zero lies in. If there is no sign change between poly(xm) | ||
208 | and poly(xl) set interval between xm and xr else set | ||
209 | interval between xl and xr and repeat till root is located | ||
210 | within the specified limits */ | ||
211 | |||
212 | if(((psumr*psuml)<0.0) || (psumr == 0.0)){ | ||
213 | roots++; | ||
214 | |||
215 | psumm=psuml; | ||
216 | for(k=0;k<=nb;k++){ | ||
217 | xm = (xl+xr)/2; /* bisect the interval */ | ||
218 | psumm=cheb_poly_eva(pt,xm,order); | ||
219 | if(psumm*psuml>0.){ | ||
220 | psuml=psumm; | ||
221 | xl=xm; | ||
222 | } | ||
223 | else{ | ||
224 | psumr=psumm; | ||
225 | xr=xm; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /* once zero is found, reset initial interval to xr */ | ||
230 | freq[j] = (xm); | ||
231 | xl = xm; | ||
232 | flag = 0; /* reset flag for next search */ | ||
233 | } | ||
234 | else{ | ||
235 | psuml=temp_psumr; | ||
236 | xl=temp_xr; | ||
237 | } | ||
238 | } | ||
239 | } | 233 | } |
234 | } | ||
240 | 235 | ||
241 | /* convert from x domain to radians */ | 236 | /* convert from x domain to radians */ |
242 | 237 | ||
243 | for(i=0; i<order; i++) { | 238 | for (i = 0; i < order; i++) { |
244 | freq[i] = acosf(freq[i]); | 239 | freq[i] = acosf(freq[i]); |
245 | } | 240 | } |
246 | 241 | ||
247 | return(roots); | 242 | return (roots); |
248 | } | 243 | } |
249 | 244 | ||
250 | /*---------------------------------------------------------------------------*\ | 245 | /*---------------------------------------------------------------------------*\ |
@@ -263,59 +258,56 @@ void lsp_to_lpc(float *lsp, float *ak, int order) | |||
263 | /* float *ak array of LPC coefficients */ | 258 | /* float *ak array of LPC coefficients */ |
264 | /* int order order of LPC coefficients */ | 259 | /* int order order of LPC coefficients */ |
265 | 260 | ||
266 | |||
267 | { | 261 | { |
268 | int i,j; | 262 | int i, j; |
269 | float xout1,xout2,xin1,xin2; | 263 | float xout1, xout2, xin1, xin2; |
270 | float *pw,*n1,*n2,*n3,*n4 = 0; | 264 | float *pw, *n1, *n2, *n3, *n4 = 0; |
271 | float freq[order]; | 265 | float freq[order]; |
272 | float Wp[(order * 4) + 2]; | 266 | float Wp[(order * 4) + 2]; |
273 | 267 | ||
274 | /* convert from radians to the x=cos(w) domain */ | 268 | /* convert from radians to the x=cos(w) domain */ |
275 | 269 | ||
276 | for(i=0; i<order; i++) | 270 | for (i = 0; i < order; i++) freq[i] = cosf(lsp[i]); |
277 | freq[i] = cosf(lsp[i]); | 271 | |
278 | 272 | pw = Wp; | |
279 | pw = Wp; | 273 | |
280 | 274 | /* initialise contents of array */ | |
281 | /* initialise contents of array */ | 275 | |
282 | 276 | for (i = 0; i <= 4 * (order / 2) + 1; i++) { /* set contents of buffer to 0 */ | |
283 | for(i=0;i<=4*(order/2)+1;i++){ /* set contents of buffer to 0 */ | 277 | *pw++ = 0.0; |
284 | *pw++ = 0.0; | 278 | } |
285 | } | 279 | |
286 | 280 | /* Set pointers up */ | |
287 | /* Set pointers up */ | 281 | |
288 | 282 | pw = Wp; | |
289 | pw = Wp; | 283 | xin1 = 1.0; |
290 | xin1 = 1.0; | 284 | xin2 = 1.0; |
291 | xin2 = 1.0; | 285 | |
292 | 286 | /* reconstruct P(z) and Q(z) by cascading second order polynomials | |
293 | /* reconstruct P(z) and Q(z) by cascading second order polynomials | 287 | in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */ |
294 | in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */ | 288 | |
295 | 289 | for (j = 0; j <= order; j++) { | |
296 | for(j=0;j<=order;j++){ | 290 | for (i = 0; i < (order / 2); i++) { |
297 | for(i=0;i<(order/2);i++){ | 291 | n1 = pw + (i * 4); |
298 | n1 = pw+(i*4); | 292 | n2 = n1 + 1; |
299 | n2 = n1 + 1; | 293 | n3 = n2 + 1; |
300 | n3 = n2 + 1; | 294 | n4 = n3 + 1; |
301 | n4 = n3 + 1; | 295 | xout1 = xin1 - 2 * (freq[2 * i]) * *n1 + *n2; |
302 | xout1 = xin1 - 2*(freq[2*i]) * *n1 + *n2; | 296 | xout2 = xin2 - 2 * (freq[2 * i + 1]) * *n3 + *n4; |
303 | xout2 = xin2 - 2*(freq[2*i+1]) * *n3 + *n4; | 297 | *n2 = *n1; |
304 | *n2 = *n1; | 298 | *n4 = *n3; |
305 | *n4 = *n3; | 299 | *n1 = xin1; |
306 | *n1 = xin1; | 300 | *n3 = xin2; |
307 | *n3 = xin2; | 301 | xin1 = xout1; |
308 | xin1 = xout1; | 302 | xin2 = xout2; |
309 | xin2 = xout2; | ||
310 | } | ||
311 | xout1 = xin1 + *(n4+1); | ||
312 | xout2 = xin2 - *(n4+2); | ||
313 | ak[j] = (xout1 + xout2)*0.5; | ||
314 | *(n4+1) = xin1; | ||
315 | *(n4+2) = xin2; | ||
316 | |||
317 | xin1 = 0.0; | ||
318 | xin2 = 0.0; | ||
319 | } | 303 | } |
304 | xout1 = xin1 + *(n4 + 1); | ||
305 | xout2 = xin2 - *(n4 + 2); | ||
306 | ak[j] = (xout1 + xout2) * 0.5; | ||
307 | *(n4 + 1) = xin1; | ||
308 | *(n4 + 2) = xin2; | ||
309 | |||
310 | xin1 = 0.0; | ||
311 | xin2 = 0.0; | ||
312 | } | ||
320 | } | 313 | } |
321 | |||
@@ -31,7 +31,7 @@ | |||
31 | #ifndef __LSP__ | 31 | #ifndef __LSP__ |
32 | #define __LSP__ | 32 | #define __LSP__ |
33 | 33 | ||
34 | int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta); | 34 | int lpc_to_lsp(float *a, int lpcrdr, float *freq, int nb, float delta); |
35 | void lsp_to_lpc(float *freq, float *ak, int lpcrdr); | 35 | void lsp_to_lpc(float *freq, float *ak, int lpcrdr); |
36 | 36 | ||
37 | #endif | 37 | #endif |
@@ -4,7 +4,7 @@ | |||
4 | AUTHOR......: David Rowe | 4 | AUTHOR......: David Rowe |
5 | DATE CREATED: May 2 2013 | 5 | DATE CREATED: May 2 2013 |
6 | 6 | ||
7 | Machine dependant functions, e.g. profiling that requires access to a clock | 7 | Machine dependent functions, e.g. profiling that requires access to a clock |
8 | counter register. | 8 | counter register. |
9 | 9 | ||
10 | \*---------------------------------------------------------------------------*/ | 10 | \*---------------------------------------------------------------------------*/ |
@@ -33,9 +33,9 @@ | |||
33 | #define PROFILE_VAR(...) unsigned int __VA_ARGS__ | 33 | #define PROFILE_VAR(...) unsigned int __VA_ARGS__ |
34 | #define PROFILE_SAMPLE(timestamp) timestamp = machdep_profile_sample() | 34 | #define PROFILE_SAMPLE(timestamp) timestamp = machdep_profile_sample() |
35 | #define PROFILE_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) \ | 35 | #define PROFILE_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) \ |
36 | timestamp = machdep_profile_sample_and_log(prev_timestamp, label) | 36 | timestamp = machdep_profile_sample_and_log(prev_timestamp, label) |
37 | #define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) \ | 37 | #define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) \ |
38 | machdep_profile_sample_and_log(prev_timestamp, label) | 38 | machdep_profile_sample_and_log(prev_timestamp, label) |
39 | #else | 39 | #else |
40 | #define PROFILE_VAR(...) | 40 | #define PROFILE_VAR(...) |
41 | #define PROFILE_SAMPLE(timestamp) | 41 | #define PROFILE_SAMPLE(timestamp) |
@@ -43,10 +43,10 @@ | |||
43 | #define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) | 43 | #define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | void machdep_profile_init(void); | 46 | void machdep_profile_init(void); |
47 | void machdep_profile_reset(void); | 47 | void machdep_profile_reset(void); |
48 | unsigned int machdep_profile_sample(void); | 48 | unsigned int machdep_profile_sample(void); |
49 | unsigned int machdep_profile_sample_and_log(unsigned int start, char s[]); | 49 | unsigned int machdep_profile_sample_and_log(unsigned int start, char s[]); |
50 | void machdep_profile_print_logged_samples(void); | 50 | void machdep_profile_print_logged_samples(void); |
51 | 51 | ||
52 | #endif | 52 | #endif |
@@ -14,6 +14,8 @@ int main() { | |||
14 | int off = 0; | 14 | int off = 0; |
15 | unsigned char bits[128]; | 15 | unsigned char bits[128]; |
16 | 16 | ||
17 | fprintf(stderr, "%d samples per frame, %d bits per frame\n", nsam, nbit); | ||
18 | |||
17 | fread(input, 976692, 1, f); | 19 | fread(input, 976692, 1, f); |
18 | fclose(f); | 20 | fclose(f); |
19 | 21 | ||
@@ -27,42 +27,48 @@ | |||
27 | 27 | ||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "mbest.h" | ||
31 | |||
30 | #include <assert.h> | 32 | #include <assert.h> |
31 | #include <math.h> | 33 | #include <math.h> |
32 | #include <stdio.h> | 34 | #include <stdio.h> |
33 | #include <stdlib.h> | 35 | #include <stdlib.h> |
34 | #include <string.h> | 36 | #include <string.h> |
35 | 37 | ||
36 | #include "mbest.h" | ||
37 | |||
38 | struct MBEST *mbest_create(int entries) { | 38 | struct MBEST *mbest_create(int entries) { |
39 | int i,j; | 39 | int i, j; |
40 | struct MBEST *mbest; | 40 | struct MBEST *mbest; |
41 | 41 | ||
42 | assert(entries > 0); | 42 | assert(entries > 0); |
43 | mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); | 43 | mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); |
44 | assert(mbest != NULL); | 44 | assert(mbest != NULL); |
45 | 45 | ||
46 | mbest->entries = entries; | 46 | mbest->entries = entries; |
47 | mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST)); | 47 | mbest->list = |
48 | assert(mbest->list != NULL); | 48 | (struct MBEST_LIST *)malloc(entries * sizeof(struct MBEST_LIST)); |
49 | assert(mbest->list != NULL); | ||
49 | 50 | ||
50 | for(i=0; i<mbest->entries; i++) { | 51 | for (i = 0; i < mbest->entries; i++) { |
51 | for(j=0; j<MBEST_STAGES; j++) | 52 | for (j = 0; j < MBEST_STAGES; j++) mbest->list[i].index[j] = 0; |
52 | mbest->list[i].index[j] = 0; | 53 | mbest->list[i].error = 1E32; |
53 | mbest->list[i].error = 1E32; | 54 | } |
54 | } | ||
55 | 55 | ||
56 | return mbest; | 56 | return mbest; |
57 | } | 57 | } |
58 | 58 | ||
59 | |||
60 | void mbest_destroy(struct MBEST *mbest) { | 59 | void mbest_destroy(struct MBEST *mbest) { |
61 | assert(mbest != NULL); | 60 | assert(mbest != NULL); |
62 | free(mbest->list); | 61 | free(mbest->list); |
63 | free(mbest); | 62 | free(mbest); |
64 | } | 63 | } |
65 | 64 | ||
65 | /* apply weighting to VQ for efficient VQ search */ | ||
66 | |||
67 | void mbest_precompute_weight(float cb[], float w[], int k, int m) { | ||
68 | for (int j = 0; j < m; j++) { | ||
69 | for (int i = 0; i < k; i++) cb[k * j + i] *= w[i]; | ||
70 | } | ||
71 | } | ||
66 | 72 | ||
67 | /*---------------------------------------------------------------------------*\ | 73 | /*---------------------------------------------------------------------------*\ |
68 | 74 | ||
@@ -75,36 +81,31 @@ void mbest_destroy(struct MBEST *mbest) { | |||
75 | \*---------------------------------------------------------------------------*/ | 81 | \*---------------------------------------------------------------------------*/ |
76 | 82 | ||
77 | void mbest_insert(struct MBEST *mbest, int index[], float error) { | 83 | void mbest_insert(struct MBEST *mbest, int index[], float error) { |
78 | int i, j, found; | 84 | int i, found; |
79 | struct MBEST_LIST *list = mbest->list; | 85 | struct MBEST_LIST *list = mbest->list; |
80 | int entries = mbest->entries; | 86 | int entries = mbest->entries; |
81 | 87 | ||
82 | found = 0; | 88 | found = 0; |
83 | for(i=0; i<entries && !found; i++) | 89 | for (i = 0; i < entries && !found; i++) |
84 | if (error < list[i].error) { | 90 | if (error < list[i].error) { |
85 | found = 1; | 91 | found = 1; |
86 | for(j=entries-1; j>i; j--) | 92 | memmove(&list[i + 1], &list[i], |
87 | list[j] = list[j-1]; | 93 | sizeof(struct MBEST_LIST) * (entries - i - 1)); |
88 | for(j=0; j<MBEST_STAGES; j++) | 94 | memcpy(&list[i].index[0], &index[0], sizeof(int) * MBEST_STAGES); |
89 | list[i].index[j] = index[j]; | 95 | list[i].error = error; |
90 | list[i].error = error; | 96 | } |
91 | } | ||
92 | } | 97 | } |
93 | 98 | ||
99 | void mbest_print(char title[], struct MBEST *mbest) { | ||
100 | int i, j; | ||
94 | 101 | ||
95 | #ifdef MBEST_PRINT_OUT | 102 | fprintf(stderr, "%s\n", title); |
96 | static void mbest_print(char title[], struct MBEST *mbest) { | 103 | for (i = 0; i < mbest->entries; i++) { |
97 | int i,j; | 104 | for (j = 0; j < MBEST_STAGES; j++) |
98 | 105 | fprintf(stderr, " %4d ", mbest->list[i].index[j]); | |
99 | fprintf(stderr, "%s\n", title); | 106 | fprintf(stderr, " %f\n", (double)mbest->list[i].error); |
100 | for(i=0; i<mbest->entries; i++) { | 107 | } |
101 | for(j=0; j<MBEST_STAGES; j++) | ||
102 | fprintf(stderr, " %4d ", mbest->list[i].index[j]); | ||
103 | fprintf(stderr, " %f\n", mbest->list[i].error); | ||
104 | } | ||
105 | } | 108 | } |
106 | #endif | ||
107 | |||
108 | 109 | ||
109 | /*---------------------------------------------------------------------------*\ | 110 | /*---------------------------------------------------------------------------*\ |
110 | 111 | ||
@@ -115,31 +116,48 @@ static void mbest_print(char title[], struct MBEST *mbest) { | |||
115 | 116 | ||
116 | \*---------------------------------------------------------------------------*/ | 117 | \*---------------------------------------------------------------------------*/ |
117 | 118 | ||
118 | void mbest_search( | 119 | void mbest_search(const float *cb, /* VQ codebook to search */ |
119 | const float *cb, /* VQ codebook to search */ | 120 | float vec[], /* target vector */ |
120 | float vec[], /* target vector */ | 121 | int k, /* dimension of vector */ |
121 | float w[], /* weighting vector */ | 122 | int m, /* number on entries in codebook */ |
122 | int k, /* dimension of vector */ | 123 | struct MBEST *mbest, /* list of closest matches */ |
123 | int m, /* number on entries in codebook */ | 124 | int index[] /* indexes that lead us here */ |
124 | struct MBEST *mbest, /* list of closest matches */ | 125 | ) { |
125 | int index[] /* indexes that lead us here */ | 126 | int j; |
126 | ) | 127 | |
127 | { | 128 | /* note weighting can be applied externally by modifying cb[] and vec: |
128 | float e; | 129 | |
129 | int i,j; | 130 | float e = 0.0; |
130 | float diff; | 131 | for(i=0; i<k; i++) |
131 | 132 | e += pow(w[i]*(cb[j*k+i] - vec[i]),2.0) | |
132 | for(j=0; j<m; j++) { | 133 | |
133 | e = 0.0; | 134 | | |
134 | for(i=0; i<k; i++) { | 135 | \|/ |
135 | diff = cb[j*k+i]-vec[i]; | 136 | |
136 | e += diff*w[i]*diff*w[i]; | 137 | for(i=0; i<k; i++) |
137 | } | 138 | e += pow(w[i]*cb[j*k+i] - w[i]*vec[i]),2.0) |
138 | index[0] = j; | 139 | |
139 | mbest_insert(mbest, index, e); | 140 | | |
140 | } | 141 | \|/ |
141 | } | ||
142 | 142 | ||
143 | for(i=0; i<k; i++) | ||
144 | e += pow(cb1[j*k+i] - vec1[i]),2.0) | ||
145 | |||
146 | where cb1[j*k+i] = w[i]*cb[j*k+i], and vec1[i] = w[i]*vec[i] | ||
147 | */ | ||
148 | |||
149 | for (j = 0; j < m; j++) { | ||
150 | float e = 0.0; | ||
151 | for (int i = 0; i < k; i++) { | ||
152 | float diff = *cb++ - vec[i]; | ||
153 | e += diff * diff; | ||
154 | } | ||
155 | |||
156 | index[0] = j; | ||
157 | if (e < mbest->list[mbest->entries - 1].error) | ||
158 | mbest_insert(mbest, index, e); | ||
159 | } | ||
160 | } | ||
143 | 161 | ||
144 | /*---------------------------------------------------------------------------*\ | 162 | /*---------------------------------------------------------------------------*\ |
145 | 163 | ||
@@ -148,26 +166,26 @@ void mbest_search( | |||
148 | Searches vec[] to a codebbook of vectors, and maintains a list of the mbest | 166 | Searches vec[] to a codebbook of vectors, and maintains a list of the mbest |
149 | closest matches. Only searches the first NewAmp2_K Vectors | 167 | closest matches. Only searches the first NewAmp2_K Vectors |
150 | 168 | ||
151 | \*---------------------------------------------------------------------------*/ | 169 | \*---------------------------------------------------------------------------*/ |
152 | 170 | ||
153 | void mbest_search450(const float *cb, float vec[], float w[], int k,int shorterK, int m, struct MBEST *mbest, int index[]) | 171 | void mbest_search450(const float *cb, float vec[], float w[], int k, |
172 | int shorterK, int m, struct MBEST *mbest, int index[]) | ||
154 | 173 | ||
155 | { | 174 | { |
156 | float e; | 175 | float e; |
157 | int i,j; | 176 | int i, j; |
158 | float diff; | 177 | float diff; |
159 | 178 | ||
160 | for(j=0; j<m; j++) { | 179 | for (j = 0; j < m; j++) { |
161 | e = 0.0; | 180 | e = 0.0; |
162 | for(i=0; i<k; i++) { | 181 | for (i = 0; i < k; i++) { |
163 | //Only search first NEWAMP2_K Vectors | 182 | // Only search first NEWAMP2_K Vectors |
164 | if(i<shorterK){ | 183 | if (i < shorterK) { |
165 | diff = cb[j*k+i]-vec[i]; | 184 | diff = cb[j * k + i] - vec[i]; |
166 | e += diff*w[i] * diff*w[i]; | 185 | e += diff * w[i] * diff * w[i]; |
167 | } | 186 | } |
168 | } | ||
169 | index[0] = j; | ||
170 | mbest_insert(mbest, index, e); | ||
171 | } | 187 | } |
188 | index[0] = j; | ||
189 | mbest_insert(mbest, index, e); | ||
190 | } | ||
172 | } | 191 | } |
173 | |||
@@ -33,27 +33,24 @@ | |||
33 | #define MBEST_STAGES 4 | 33 | #define MBEST_STAGES 4 |
34 | 34 | ||
35 | struct MBEST_LIST { | 35 | struct MBEST_LIST { |
36 | int index[MBEST_STAGES]; /* index of each stage that lead us to this error */ | 36 | int index[MBEST_STAGES]; /* index of each stage that lead us to this error */ |
37 | float error; | 37 | float error; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct MBEST { | 40 | struct MBEST { |
41 | int entries; /* number of entries in mbest list */ | 41 | int entries; /* number of entries in mbest list */ |
42 | struct MBEST_LIST *list; | 42 | struct MBEST_LIST *list; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct MBEST *mbest_create(int entries); | 45 | struct MBEST *mbest_create(int entries); |
46 | void mbest_destroy(struct MBEST *mbest); | 46 | void mbest_destroy(struct MBEST *mbest); |
47 | void mbest_precompute_weight(float cb[], float w[], int k, int m); | ||
47 | void mbest_insert(struct MBEST *mbest, int index[], float error); | 48 | void mbest_insert(struct MBEST *mbest, int index[], float error); |
48 | void mbest_search(const float *cb, float vec[], float w[], int k, int m, struct MBEST *mbest, int index[]); | 49 | void mbest_search(const float *cb, float vec[], int k, int m, |
49 | void mbest_search450(const float *cb, float vec[], float w[], int k,int shorterK, int m, struct MBEST *mbest, int index[]); | 50 | struct MBEST *mbest, int index[]); |
50 | 51 | void mbest_search450(const float *cb, float vec[], float w[], int k, | |
51 | // #define MBEST_PRINT_OUT | 52 | int shorterK, int m, struct MBEST *mbest, int index[]); |
52 | #ifdef MBEST_PRINT_OUT | ||
53 | #define MBEST_PRINT(a,b) mbest_print((a),(b)) | ||
54 | #else | ||
55 | #define MBEST_PRINT(a,b) | ||
56 | #endif | ||
57 | 53 | ||
54 | void mbest_print(char title[], struct MBEST *mbest); | ||
58 | 55 | ||
59 | #endif | 56 | #endif |
@@ -28,19 +28,18 @@ | |||
28 | 28 | ||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "newamp1.h" | ||
32 | |||
31 | #include <assert.h> | 33 | #include <assert.h> |
34 | #include <math.h> | ||
32 | #include <stdio.h> | 35 | #include <stdio.h> |
33 | #include <stdlib.h> | 36 | #include <stdlib.h> |
34 | #include <string.h> | 37 | #include <string.h> |
35 | #include <math.h> | ||
36 | 38 | ||
37 | #include "defines.h" | 39 | #include "defines.h" |
40 | #include "mbest.h" | ||
38 | #include "phase.h" | 41 | #include "phase.h" |
39 | #include "quantise.h" | 42 | #include "quantise.h" |
40 | #include "mbest.h" | ||
41 | #include "newamp1.h" | ||
42 | |||
43 | #define NEWAMP1_VQ_MBEST_DEPTH 5 /* how many candidates we keep for each stage of mbest search */ | ||
44 | 43 | ||
45 | /*---------------------------------------------------------------------------*\ | 44 | /*---------------------------------------------------------------------------*\ |
46 | 45 | ||
@@ -48,39 +47,44 @@ | |||
48 | AUTHOR......: David Rowe | 47 | AUTHOR......: David Rowe |
49 | DATE CREATED: Jan 2017 | 48 | DATE CREATED: Jan 2017 |
50 | 49 | ||
51 | General 2nd order parabolic interpolator. Used splines orginally, | 50 | General 2nd order parabolic interpolator. Used splines originally, |
52 | but this is much simpler and we don't need much accuracy. Given two | 51 | but this is much simpler and we don't need much accuracy. Given two |
53 | vectors of points xp and yp, find interpolated values y at points x. | 52 | vectors of points xp and yp, find interpolated values y at points x. |
54 | 53 | ||
55 | \*---------------------------------------------------------------------------*/ | 54 | \*---------------------------------------------------------------------------*/ |
56 | 55 | ||
57 | void interp_para(float y[], float xp[], float yp[], int np, float x[], int n) | 56 | void interp_para(float y[], float xp[], float yp[], int np, float x[], int n) { |
58 | { | 57 | assert(np >= 3); |
59 | assert(np >= 3); | ||
60 | 58 | ||
61 | int k,i; | 59 | int k, i; |
62 | float xi, x1, y1, x2, y2, x3, y3, a, b; | 60 | float xi, x1, y1, x2, y2, x3, y3, a, b; |
63 | 61 | ||
64 | k = 0; | 62 | k = 0; |
65 | for (i=0; i<n; i++) { | 63 | for (i = 0; i < n; i++) { |
66 | xi = x[i]; | 64 | xi = x[i]; |
67 | 65 | ||
68 | /* k is index into xp of where we start 3 points used to form parabola */ | 66 | /* k is index into xp of where we start 3 points used to form parabola */ |
69 | 67 | ||
70 | while ((xp[k+1] < xi) && (k < (np-3))) | 68 | while ((xp[k + 1] < xi) && (k < (np - 3))) k++; |
71 | k++; | ||
72 | |||
73 | x1 = xp[k]; y1 = yp[k]; x2 = xp[k+1]; y2 = yp[k+1]; x3 = xp[k+2]; y3 = yp[k+2]; | ||
74 | 69 | ||
75 | //printf("k: %d np: %d i: %d xi: %f x1: %f y1: %f\n", k, np, i, xi, x1, y1); | 70 | x1 = xp[k]; |
71 | y1 = yp[k]; | ||
72 | x2 = xp[k + 1]; | ||
73 | y2 = yp[k + 1]; | ||
74 | x3 = xp[k + 2]; | ||
75 | y3 = yp[k + 2]; | ||
76 | 76 | ||
77 | a = ((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))/(x3-x1); | 77 | // printf("k: %d np: %d i: %d xi: %f x1: %f y1: %f\n", k, np, i, xi, x1, |
78 | b = ((y3-y2)/(x3-x2)*(x2-x1)+(y2-y1)/(x2-x1)*(x3-x2))/(x3-x1); | 78 | // y1); |
79 | |||
80 | y[i] = a*(xi-x2)*(xi-x2) + b*(xi-x2) + y2; | ||
81 | } | ||
82 | } | ||
83 | 79 | ||
80 | a = ((y3 - y2) / (x3 - x2) - (y2 - y1) / (x2 - x1)) / (x3 - x1); | ||
81 | b = ((y3 - y2) / (x3 - x2) * (x2 - x1) + | ||
82 | (y2 - y1) / (x2 - x1) * (x3 - x2)) / | ||
83 | (x3 - x1); | ||
84 | |||
85 | y[i] = a * (xi - x2) * (xi - x2) + b * (xi - x2) + y2; | ||
86 | } | ||
87 | } | ||
84 | 88 | ||
85 | /*---------------------------------------------------------------------------*\ | 89 | /*---------------------------------------------------------------------------*\ |
86 | 90 | ||
@@ -94,24 +98,23 @@ void interp_para(float y[], float xp[], float yp[], int np, float x[], int n) | |||
94 | \*---------------------------------------------------------------------------*/ | 98 | \*---------------------------------------------------------------------------*/ |
95 | 99 | ||
96 | float ftomel(float fHz) { | 100 | float ftomel(float fHz) { |
97 | float mel = floorf(2595.0*log10f(1.0 + fHz/700.0)+0.5); | 101 | float mel = floorf(2595.0 * log10f(1.0 + fHz / 700.0) + 0.5); |
98 | return mel; | 102 | return mel; |
99 | } | 103 | } |
100 | 104 | ||
101 | void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, float mel_start, float mel_end) | 105 | void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, |
102 | { | 106 | float mel_start, float mel_end) { |
103 | float step = (mel_end-mel_start)/(K-1); | 107 | float step = (mel_end - mel_start) / (K - 1); |
104 | float mel; | 108 | float mel; |
105 | int k; | 109 | int k; |
106 | 110 | ||
107 | mel = mel_start; | 111 | mel = mel_start; |
108 | for (k=0; k<K; k++) { | 112 | for (k = 0; k < K; k++) { |
109 | rate_K_sample_freqs_kHz[k] = 0.7*(POW10F(mel/2595.0) - 1.0); | 113 | rate_K_sample_freqs_kHz[k] = 0.7 * (POW10F(mel / 2595.0) - 1.0); |
110 | mel += step; | 114 | mel += step; |
111 | } | 115 | } |
112 | } | 116 | } |
113 | 117 | ||
114 | |||
115 | /*---------------------------------------------------------------------------*\ | 118 | /*---------------------------------------------------------------------------*\ |
116 | 119 | ||
117 | FUNCTION....: resample_const_rate_f() | 120 | FUNCTION....: resample_const_rate_f() |
@@ -122,35 +125,36 @@ void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, float mel_star | |||
122 | 125 | ||
123 | \*---------------------------------------------------------------------------*/ | 126 | \*---------------------------------------------------------------------------*/ |
124 | 127 | ||
125 | void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K) | 128 | void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], |
126 | { | 129 | float rate_K_sample_freqs_kHz[], int K) { |
127 | int m; | 130 | int m; |
128 | float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1], AmdB_peak; | 131 | float AmdB[MAX_AMP + 1], rate_L_sample_freqs_kHz[MAX_AMP + 1], AmdB_peak; |
129 | 132 | ||
130 | /* convert rate L=pi/Wo amplitude samples to fixed rate K */ | 133 | /* convert rate L=pi/Wo amplitude samples to fixed rate K */ |
131 | 134 | ||
132 | AmdB_peak = -100.0; | 135 | AmdB_peak = -100.0; |
133 | for(m=1; m<=model->L; m++) { | 136 | for (m = 1; m <= model->L; m++) { |
134 | AmdB[m] = 20.0*log10f(model->A[m]+1E-16); | 137 | AmdB[m] = 20.0 * log10f(model->A[m] + 1E-16); |
135 | if (AmdB[m] > AmdB_peak) { | 138 | if (AmdB[m] > AmdB_peak) { |
136 | AmdB_peak = AmdB[m]; | 139 | AmdB_peak = AmdB[m]; |
137 | } | ||
138 | rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI; | ||
139 | //printf("m: %d AmdB: %f AmdB_peak: %f sf: %f\n", m, AmdB[m], AmdB_peak, rate_L_sample_freqs_kHz[m]); | ||
140 | } | 140 | } |
141 | 141 | rate_L_sample_freqs_kHz[m] = m * model->Wo * (c2const->Fs / 2000.0) / M_PI; | |
142 | /* clip between peak and peak -50dB, to reduce dynamic range */ | 142 | // printf("m: %d AmdB: %f AmdB_peak: %f sf: %f\n", m, AmdB[m], AmdB_peak, |
143 | // rate_L_sample_freqs_kHz[m]); | ||
144 | } | ||
145 | |||
146 | /* clip between peak and peak -50dB, to reduce dynamic range */ | ||
143 | 147 | ||
144 | for(m=1; m<=model->L; m++) { | 148 | for (m = 1; m <= model->L; m++) { |
145 | if (AmdB[m] < (AmdB_peak-50.0)) { | 149 | if (AmdB[m] < (AmdB_peak - 50.0)) { |
146 | AmdB[m] = AmdB_peak-50.0; | 150 | AmdB[m] = AmdB_peak - 50.0; |
147 | } | ||
148 | } | 151 | } |
152 | } | ||
149 | 153 | ||
150 | interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, rate_K_sample_freqs_kHz, K); | 154 | interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, |
155 | rate_K_sample_freqs_kHz, K); | ||
151 | } | 156 | } |
152 | 157 | ||
153 | |||
154 | /*---------------------------------------------------------------------------*\ | 158 | /*---------------------------------------------------------------------------*\ |
155 | 159 | ||
156 | FUNCTION....: rate_K_mbest_encode | 160 | FUNCTION....: rate_K_mbest_encode |
@@ -161,64 +165,55 @@ void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], f | |||
161 | 165 | ||
162 | \*---------------------------------------------------------------------------*/ | 166 | \*---------------------------------------------------------------------------*/ |
163 | 167 | ||
164 | float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries) | 168 | float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, |
165 | { | 169 | int mbest_entries) { |
166 | int i, j, n1, n2; | 170 | int i, j, n1, n2; |
167 | const float *codebook1 = newamp1vq_cb[0].cb; | 171 | const float *codebook1 = newamp1vq_cb[0].cb; |
168 | const float *codebook2 = newamp1vq_cb[1].cb; | 172 | const float *codebook2 = newamp1vq_cb[1].cb; |
169 | struct MBEST *mbest_stage1, *mbest_stage2; | 173 | struct MBEST *mbest_stage1, *mbest_stage2; |
170 | float target[ndim]; | 174 | float target[ndim]; |
171 | float w[ndim]; | 175 | int index[MBEST_STAGES]; |
172 | int index[MBEST_STAGES]; | ||
173 | float mse, tmp; | 176 | float mse, tmp; |
174 | 177 | ||
175 | /* codebook is compiled for a fixed K */ | 178 | /* codebook is compiled for a fixed K */ |
176 | 179 | ||
177 | assert(ndim == newamp1vq_cb[0].k); | 180 | assert(ndim == newamp1vq_cb[0].k); |
178 | 181 | ||
179 | /* equal weights, could be argued mel freq axis gives freq dep weighting */ | ||
180 | |||
181 | for(i=0; i<ndim; i++) | ||
182 | w[i] = 1.0; | ||
183 | |||
184 | mbest_stage1 = mbest_create(mbest_entries); | 182 | mbest_stage1 = mbest_create(mbest_entries); |
185 | mbest_stage2 = mbest_create(mbest_entries); | 183 | mbest_stage2 = mbest_create(mbest_entries); |
186 | for(i=0; i<MBEST_STAGES; i++) | 184 | for (i = 0; i < MBEST_STAGES; i++) index[i] = 0; |
187 | index[i] = 0; | ||
188 | 185 | ||
189 | /* Stage 1 */ | 186 | /* Stage 1 */ |
190 | 187 | ||
191 | mbest_search(codebook1, x, w, ndim, newamp1vq_cb[0].m, mbest_stage1, index); | 188 | mbest_search(codebook1, x, ndim, newamp1vq_cb[0].m, mbest_stage1, index); |
192 | MBEST_PRINT("Stage 1:", mbest_stage1); | ||
193 | 189 | ||
194 | /* Stage 2 */ | 190 | /* Stage 2 */ |
195 | 191 | ||
196 | for (j=0; j<mbest_entries; j++) { | 192 | for (j = 0; j < mbest_entries; j++) { |
197 | index[1] = n1 = mbest_stage1->list[j].index[0]; | 193 | index[1] = n1 = mbest_stage1->list[j].index[0]; |
198 | for(i=0; i<ndim; i++) | 194 | for (i = 0; i < ndim; i++) target[i] = x[i] - codebook1[ndim * n1 + i]; |
199 | target[i] = x[i] - codebook1[ndim*n1+i]; | 195 | mbest_search(codebook2, target, ndim, newamp1vq_cb[1].m, mbest_stage2, |
200 | mbest_search(codebook2, target, w, ndim, newamp1vq_cb[1].m, mbest_stage2, index); | 196 | index); |
201 | } | 197 | } |
202 | MBEST_PRINT("Stage 2:", mbest_stage2); | ||
203 | 198 | ||
204 | n1 = mbest_stage2->list[0].index[1]; | 199 | n1 = mbest_stage2->list[0].index[1]; |
205 | n2 = mbest_stage2->list[0].index[0]; | 200 | n2 = mbest_stage2->list[0].index[0]; |
206 | mse = 0.0; | 201 | mse = 0.0; |
207 | for (i=0;i<ndim;i++) { | 202 | for (i = 0; i < ndim; i++) { |
208 | tmp = codebook1[ndim*n1+i] + codebook2[ndim*n2+i]; | 203 | tmp = codebook1[ndim * n1 + i] + codebook2[ndim * n2 + i]; |
209 | mse += (x[i]-tmp)*(x[i]-tmp); | 204 | mse += (x[i] - tmp) * (x[i] - tmp); |
210 | xq[i] = tmp; | 205 | xq[i] = tmp; |
211 | } | 206 | } |
212 | 207 | ||
213 | mbest_destroy(mbest_stage1); | 208 | mbest_destroy(mbest_stage1); |
214 | mbest_destroy(mbest_stage2); | 209 | mbest_destroy(mbest_stage2); |
215 | 210 | ||
216 | indexes[0] = n1; indexes[1] = n2; | 211 | indexes[0] = n1; |
212 | indexes[1] = n2; | ||
217 | 213 | ||
218 | return mse; | 214 | return mse; |
219 | } | 215 | } |
220 | 216 | ||
221 | |||
222 | /*---------------------------------------------------------------------------*\ | 217 | /*---------------------------------------------------------------------------*\ |
223 | 218 | ||
224 | FUNCTION....: post_filter | 219 | FUNCTION....: post_filter |
@@ -226,7 +221,7 @@ float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest | |||
226 | DATE CREATED: Jan 2017 | 221 | DATE CREATED: Jan 2017 |
227 | 222 | ||
228 | Post Filter, has a big impact on speech quality after VQ. When used | 223 | Post Filter, has a big impact on speech quality after VQ. When used |
229 | on a mean removed rate K vector, it raises formants, and supresses | 224 | on a mean removed rate K vector, it raises formants, and suppresses |
230 | anti-formants. As it manipulates amplitudes, we normalise energy to | 225 | anti-formants. As it manipulates amplitudes, we normalise energy to |
231 | prevent clipping or large level variations. pf_gain of 1.2 to 1.5 | 226 | prevent clipping or large level variations. pf_gain of 1.2 to 1.5 |
232 | (dB) seems to work OK. Good area for further investigations and | 227 | (dB) seems to work OK. Good area for further investigations and |
@@ -234,37 +229,36 @@ float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest | |||
234 | 229 | ||
235 | \*---------------------------------------------------------------------------*/ | 230 | \*---------------------------------------------------------------------------*/ |
236 | 231 | ||
237 | void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain) | 232 | void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, |
238 | { | 233 | float pf_gain) { |
239 | int k; | 234 | int k; |
240 | 235 | ||
241 | /* | 236 | /* |
242 | vec is rate K vector describing spectrum of current frame lets | 237 | vec is rate K vector describing spectrum of current frame lets |
243 | pre-emp before applying PF. 20dB/dec over 300Hz. Postfilter | 238 | pre-emp before applying PF. 20dB/dec over 300Hz. Postfilter |
244 | affects energy of frame so we measure energy before and after | 239 | affects energy of frame so we measure energy before and after |
245 | and normalise. Plenty of room for experiment here as well. | 240 | and normalise. Plenty of room for experimentation here. |
246 | */ | 241 | */ |
247 | 242 | ||
248 | float pre[K]; | 243 | float pre[K]; |
249 | float e_before = 0.0; | 244 | float e_before = 0.0; |
250 | float e_after = 0.0; | 245 | float e_after = 0.0; |
251 | for(k=0; k<K; k++) { | 246 | for (k = 0; k < K; k++) { |
252 | pre[k] = 20.0*log10f(sample_freq_kHz[k]/0.3); | 247 | pre[k] = 20.0 * log10f(sample_freq_kHz[k] / 0.3); |
253 | vec[k] += pre[k]; | 248 | vec[k] += pre[k]; |
254 | e_before += POW10F(vec[k]/10.0); | 249 | e_before += POW10F(vec[k] / 10.0); |
255 | vec[k] *= pf_gain; | 250 | vec[k] *= pf_gain; |
256 | e_after += POW10F(vec[k]/10.0); | 251 | e_after += POW10F(vec[k] / 10.0); |
257 | } | 252 | } |
258 | 253 | ||
259 | float gain = e_after/e_before; | 254 | float gain = e_after / e_before; |
260 | float gaindB = 10*log10f(gain); | 255 | float gaindB = 10 * log10f(gain); |
261 | |||
262 | for(k=0; k<K; k++) { | ||
263 | vec[k] -= gaindB; | ||
264 | vec[k] -= pre[k]; | ||
265 | } | ||
266 | } | ||
267 | 256 | ||
257 | for (k = 0; k < K; k++) { | ||
258 | vec[k] -= gaindB; | ||
259 | vec[k] -= pre[k]; | ||
260 | } | ||
261 | } | ||
268 | 262 | ||
269 | /*---------------------------------------------------------------------------*\ | 263 | /*---------------------------------------------------------------------------*\ |
270 | 264 | ||
@@ -273,49 +267,46 @@ void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_g | |||
273 | DATE CREATED: Jan 2017 | 267 | DATE CREATED: Jan 2017 |
274 | 268 | ||
275 | Decoder side interpolation of Wo and voicing, to go from 25 Hz | 269 | Decoder side interpolation of Wo and voicing, to go from 25 Hz |
276 | sample rate used over channle to 100Hz internal sample rate of Codec 2. | 270 | sample rate used over channel to 100Hz internal sample rate of Codec 2. |
277 | 271 | ||
278 | \*---------------------------------------------------------------------------*/ | 272 | \*---------------------------------------------------------------------------*/ |
279 | 273 | ||
280 | void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2) | 274 | void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, |
281 | { | 275 | int voicing1, int voicing2) { |
282 | int i; | 276 | int i; |
283 | int M = 4; /* interpolation rate */ | 277 | int M = 4; /* interpolation rate */ |
284 | 278 | ||
285 | for(i=0; i<M; i++) | 279 | for (i = 0; i < M; i++) voicing_[i] = 0; |
286 | voicing_[i] = 0; | ||
287 | 280 | ||
288 | if (!voicing1 && !voicing2) { | 281 | if (!voicing1 && !voicing2) { |
289 | for(i=0; i<M; i++) | 282 | for (i = 0; i < M; i++) Wo_[i] = 2.0 * M_PI / 100.0; |
290 | Wo_[i] = 2.0*M_PI/100.0; | 283 | } |
291 | } | ||
292 | 284 | ||
293 | if (voicing1 && !voicing2) { | 285 | if (voicing1 && !voicing2) { |
294 | Wo_[0] = Wo_[1] = Wo1; | 286 | Wo_[0] = Wo_[1] = Wo1; |
295 | Wo_[2] = Wo_[3] = 2.0*M_PI/100.0; | 287 | Wo_[2] = Wo_[3] = 2.0 * M_PI / 100.0; |
296 | voicing_[0] = voicing_[1] = 1; | 288 | voicing_[0] = voicing_[1] = 1; |
297 | } | 289 | } |
298 | 290 | ||
299 | if (!voicing1 && voicing2) { | 291 | if (!voicing1 && voicing2) { |
300 | Wo_[0] = Wo_[1] = 2.0*M_PI/100.0; | 292 | Wo_[0] = Wo_[1] = 2.0 * M_PI / 100.0; |
301 | Wo_[2] = Wo_[3] = Wo2; | 293 | Wo_[2] = Wo_[3] = Wo2; |
302 | voicing_[2] = voicing_[3] = 1; | 294 | voicing_[2] = voicing_[3] = 1; |
303 | } | 295 | } |
304 | 296 | ||
305 | if (voicing1 && voicing2) { | 297 | if (voicing1 && voicing2) { |
306 | float c; | 298 | float c; |
307 | for(i=0,c=1.0; i<M; i++,c-=1.0/M) { | 299 | for (i = 0, c = 1.0; i < M; i++, c -= 1.0 / M) { |
308 | Wo_[i] = Wo1*c + Wo2*(1.0-c); | 300 | Wo_[i] = Wo1 * c + Wo2 * (1.0 - c); |
309 | voicing_[i] = 1; | 301 | voicing_[i] = 1; |
310 | } | ||
311 | } | 302 | } |
303 | } | ||
312 | 304 | ||
313 | for(i=0; i<M; i++) { | 305 | for (i = 0; i < M; i++) { |
314 | L_[i] = floorf(M_PI/Wo_[i]); | 306 | L_[i] = floorf(M_PI / Wo_[i]); |
315 | } | 307 | } |
316 | } | 308 | } |
317 | 309 | ||
318 | |||
319 | /*---------------------------------------------------------------------------*\ | 310 | /*---------------------------------------------------------------------------*\ |
320 | 311 | ||
321 | FUNCTION....: resample_rate_L | 312 | FUNCTION....: resample_rate_L |
@@ -326,36 +317,37 @@ void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, in | |||
326 | 317 | ||
327 | \*---------------------------------------------------------------------------*/ | 318 | \*---------------------------------------------------------------------------*/ |
328 | 319 | ||
329 | void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K) | 320 | void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], |
330 | { | 321 | float rate_K_sample_freqs_kHz[], int K) { |
331 | float rate_K_vec_term[K+2], rate_K_sample_freqs_kHz_term[K+2]; | 322 | float rate_K_vec_term[K + 2], rate_K_sample_freqs_kHz_term[K + 2]; |
332 | float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1]; | 323 | float AmdB[MAX_AMP + 1], rate_L_sample_freqs_kHz[MAX_AMP + 1]; |
333 | int m,k; | 324 | int m, k; |
334 | |||
335 | /* terminate either end of the rate K vecs with 0dB points */ | ||
336 | |||
337 | rate_K_vec_term[0] = rate_K_vec_term[K+1] = 0.0; | ||
338 | rate_K_sample_freqs_kHz_term[0] = 0.0; | ||
339 | rate_K_sample_freqs_kHz_term[K+1] = 4.0; | ||
340 | |||
341 | for(k=0; k<K; k++) { | ||
342 | rate_K_vec_term[k+1] = rate_K_vec[k]; | ||
343 | rate_K_sample_freqs_kHz_term[k+1] = rate_K_sample_freqs_kHz[k]; | ||
344 | |||
345 | //printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], rate_K_vec[k]); | ||
346 | } | ||
347 | |||
348 | for(m=1; m<=model->L; m++) { | ||
349 | rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI; | ||
350 | } | ||
351 | |||
352 | interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K+2, &rate_L_sample_freqs_kHz[1], model->L); | ||
353 | for(m=1; m<=model->L; m++) { | ||
354 | model->A[m] = POW10F(AmdB[m]/20.0); | ||
355 | // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]); | ||
356 | } | ||
357 | } | ||
358 | 325 | ||
326 | /* terminate either end of the rate K vecs with 0dB points */ | ||
327 | |||
328 | rate_K_vec_term[0] = rate_K_vec_term[K + 1] = 0.0; | ||
329 | rate_K_sample_freqs_kHz_term[0] = 0.0; | ||
330 | rate_K_sample_freqs_kHz_term[K + 1] = 4.0; | ||
331 | |||
332 | for (k = 0; k < K; k++) { | ||
333 | rate_K_vec_term[k + 1] = rate_K_vec[k]; | ||
334 | rate_K_sample_freqs_kHz_term[k + 1] = rate_K_sample_freqs_kHz[k]; | ||
335 | // printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], | ||
336 | // rate_K_vec[k]); | ||
337 | } | ||
338 | |||
339 | for (m = 1; m <= model->L; m++) { | ||
340 | rate_L_sample_freqs_kHz[m] = m * model->Wo * (c2const->Fs / 2000.0) / M_PI; | ||
341 | } | ||
342 | |||
343 | interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K + 2, | ||
344 | &rate_L_sample_freqs_kHz[1], model->L); | ||
345 | for (m = 1; m <= model->L; m++) { | ||
346 | model->A[m] = POW10F(AmdB[m] / 20.0); | ||
347 | // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], | ||
348 | // AmdB[m], model->A[m]); | ||
349 | } | ||
350 | } | ||
359 | 351 | ||
360 | /*---------------------------------------------------------------------------*\ | 352 | /*---------------------------------------------------------------------------*\ |
361 | 353 | ||
@@ -368,34 +360,100 @@ void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float r | |||
368 | 360 | ||
369 | \*---------------------------------------------------------------------------*/ | 361 | \*---------------------------------------------------------------------------*/ |
370 | 362 | ||
371 | void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg) | 363 | void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, |
372 | { | 364 | codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg) { |
373 | int i,m,b; | 365 | int i, m, b; |
374 | int Ns = Nfft/2+1; | 366 | int Ns = Nfft / 2 + 1; |
375 | float Gdbfk[Ns], sample_freqs_kHz[Ns], phase[Ns]; | 367 | float Gdbfk[Ns], sample_freqs_kHz[Ns], phase[Ns]; |
376 | float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1]; | 368 | float AmdB[MAX_AMP + 1], rate_L_sample_freqs_kHz[MAX_AMP + 1]; |
377 | 369 | ||
378 | for(m=1; m<=model->L; m++) { | 370 | for (m = 1; m <= model->L; m++) { |
379 | assert(model->A[m] != 0.0); | 371 | assert(model->A[m] != 0.0); |
380 | AmdB[m] = 20.0*log10f(model->A[m]); | 372 | AmdB[m] = 20.0 * log10f(model->A[m]); |
381 | rate_L_sample_freqs_kHz[m] = (float)m*model->Wo*(c2const->Fs/2000.0)/M_PI; | 373 | rate_L_sample_freqs_kHz[m] = |
382 | } | 374 | (float)m * model->Wo * (c2const->Fs / 2000.0) / M_PI; |
383 | 375 | } | |
384 | for(i=0; i<Ns; i++) { | ||
385 | sample_freqs_kHz[i] = (c2const->Fs/1000.0)*(float)i/Nfft; | ||
386 | } | ||
387 | 376 | ||
388 | interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, sample_freqs_kHz, Ns); | 377 | for (i = 0; i < Ns; i++) { |
389 | mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg); | 378 | sample_freqs_kHz[i] = (c2const->Fs / 1000.0) * (float)i / Nfft; |
379 | } | ||
390 | 380 | ||
391 | for(m=1; m<=model->L; m++) { | 381 | interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, |
392 | b = floorf(0.5+m*model->Wo*Nfft/(2.0*M_PI)); | 382 | sample_freqs_kHz, Ns); |
393 | H[m].real = cosf(phase[b]); H[m].imag = sinf(phase[b]); | 383 | mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg); |
394 | } | 384 | |
385 | for (m = 1; m <= model->L; m++) { | ||
386 | b = floorf(0.5 + m * model->Wo * Nfft / (2.0 * M_PI)); | ||
387 | H[m].real = cosf(phase[b]); | ||
388 | H[m].imag = sinf(phase[b]); | ||
389 | } | ||
395 | } | 390 | } |
396 | 391 | ||
392 | /*---------------------------------------------------------------------------* \ | ||
397 | 393 | ||
398 | /*---------------------------------------------------------------------------*\ | 394 | FUNCTION....: determine_autoc |
395 | AUTHOR......: David Rowe | ||
396 | DATE CREATED: April 2020 | ||
397 | |||
398 | Determine autocorrelation coefficients from model params, for machine | ||
399 | learning experiments. | ||
400 | |||
401 | \*---------------------------------------------------------------------------*/ | ||
402 | |||
403 | void determine_autoc(C2CONST *c2const, float Rk[], int order, MODEL *model, | ||
404 | int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg) { | ||
405 | int i, m; | ||
406 | int Ns = Nfft / 2 + 1; | ||
407 | float Gdbfk[Ns], sample_freqs_kHz[Ns]; | ||
408 | float AmdB[MAX_AMP + 1], rate_L_sample_freqs_kHz[MAX_AMP + 1]; | ||
409 | |||
410 | /* interpolate in the log domain */ | ||
411 | for (m = 1; m <= model->L; m++) { | ||
412 | assert(model->A[m] != 0.0); | ||
413 | AmdB[m] = 20.0 * log10f(model->A[m]); | ||
414 | rate_L_sample_freqs_kHz[m] = | ||
415 | (float)m * model->Wo * (c2const->Fs / 2000.0) / M_PI; | ||
416 | } | ||
417 | |||
418 | for (i = 0; i < Ns; i++) { | ||
419 | sample_freqs_kHz[i] = (c2const->Fs / 1000.0) * (float)i / Nfft; | ||
420 | } | ||
421 | |||
422 | interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, | ||
423 | sample_freqs_kHz, Ns); | ||
424 | |||
425 | COMP S[Nfft], R[Nfft]; | ||
426 | |||
427 | /* install negative frequency components, convert to mag squared of spectrum | ||
428 | */ | ||
429 | S[0].real = pow(10.0, Gdbfk[0] / 10.0); | ||
430 | S[0].imag = 0.0; | ||
431 | for (i = 1; i < Ns; i++) { | ||
432 | S[i].real = S[Nfft - i].real = pow(10.0, Gdbfk[i] / 10.0); | ||
433 | S[i].imag = S[Nfft - i].imag = 0.0; | ||
434 | } | ||
435 | |||
436 | /* IDFT of mag squared is autocorrelation function */ | ||
437 | codec2_fft(inv_cfg, S, R); | ||
438 | for (int k = 0; k < order + 1; k++) Rk[k] = R[k].real; | ||
439 | } | ||
440 | |||
441 | /* update and optionally run "front eq" equaliser on before VQ */ | ||
442 | void newamp1_eq(float rate_K_vec_no_mean[], float eq[], int K, int eq_en) { | ||
443 | static float ideal[] = {8, 10, 12, 14, 14, 14, 14, 14, 14, 14, | ||
444 | 14, 14, 14, 14, 14, 14, 14, 14, 14, -20}; | ||
445 | float gain = 0.02; | ||
446 | float update; | ||
447 | |||
448 | for (int k = 0; k < K; k++) { | ||
449 | update = rate_K_vec_no_mean[k] - ideal[k]; | ||
450 | eq[k] = (1.0 - gain) * eq[k] + gain * update; | ||
451 | if (eq[k] < 0.0) eq[k] = 0.0; | ||
452 | if (eq_en) rate_K_vec_no_mean[k] -= eq[k]; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | /*---------------------------------------------------------------------------* \ | ||
399 | 457 | ||
400 | FUNCTION....: newamp1_model_to_indexes | 458 | FUNCTION....: newamp1_model_to_indexes |
401 | AUTHOR......: David Rowe | 459 | AUTHOR......: David Rowe |
@@ -406,78 +464,53 @@ void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, codec2_ | |||
406 | 464 | ||
407 | \*---------------------------------------------------------------------------*/ | 465 | \*---------------------------------------------------------------------------*/ |
408 | 466 | ||
409 | void newamp1_model_to_indexes(C2CONST *c2const, | 467 | void newamp1_model_to_indexes(C2CONST *c2const, int indexes[], MODEL *model, |
410 | int indexes[], | 468 | float rate_K_vec[], |
411 | MODEL *model, | 469 | float rate_K_sample_freqs_kHz[], int K, |
412 | float rate_K_vec[], | 470 | float *mean, float rate_K_vec_no_mean[], |
413 | float rate_K_sample_freqs_kHz[], | 471 | float rate_K_vec_no_mean_[], float *se, float *eq, |
414 | int K, | 472 | int eq_en) { |
415 | float *mean, | 473 | int k; |
416 | float rate_K_vec_no_mean[], | 474 | |
417 | float rate_K_vec_no_mean_[], | 475 | /* convert variable rate L to fixed rate K */ |
418 | float *se, | 476 | resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K); |
419 | float *eq, | 477 | |
420 | int eq_en | 478 | /* remove mean */ |
421 | ) | 479 | float sum = 0.0; |
422 | { | 480 | for (k = 0; k < K; k++) sum += rate_K_vec[k]; |
423 | int k; | 481 | *mean = sum / K; |
424 | 482 | for (k = 0; k < K; k++) rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean; | |
425 | /* convert variable rate L to fixed rate K */ | 483 | |
426 | resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K); | 484 | /* update and optionally run "front eq" equaliser on before VQ */ |
427 | 485 | newamp1_eq(rate_K_vec_no_mean, eq, K, eq_en); | |
428 | /* remove mean */ | 486 | |
429 | float sum = 0.0; | 487 | /* two stage VQ */ |
430 | for(k=0; k<K; k++) | 488 | rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, K, |
431 | sum += rate_K_vec[k]; | 489 | NEWAMP1_VQ_MBEST_DEPTH); |
432 | *mean = sum/K; | 490 | |
433 | for(k=0; k<K; k++) | 491 | /* running sum of squared error for variance calculation */ |
434 | rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean; | 492 | for (k = 0; k < K; k++) |
435 | 493 | *se += (float)pow(rate_K_vec_no_mean[k] - rate_K_vec_no_mean_[k], 2.0); | |
436 | /* update and optionally run "front eq" equaliser on before VQ */ | 494 | |
437 | static float ideal[] = {8,10,12,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,-20}; | 495 | /* scalar quantise mean (effectively the frame energy) */ |
438 | float gain = 0.02; | 496 | float w[1] = {1.0}; |
439 | float update; | 497 | float se_mean; |
440 | 498 | indexes[2] = | |
441 | for(k=0; k<K; k++) { | 499 | quantise(newamp1_energy_cb[0].cb, mean, w, newamp1_energy_cb[0].k, |
442 | update = rate_K_vec_no_mean[k] - ideal[k]; | 500 | newamp1_energy_cb[0].m, &se_mean); |
443 | eq[k] = (1.0-gain)*eq[k] + gain*update; | 501 | |
444 | if (eq[k] < 0.0) eq[k] = 0.0; | 502 | /* scalar quantise Wo. We steal the smallest Wo index to signal |
445 | if (eq_en) | 503 | an unvoiced frame */ |
446 | rate_K_vec_no_mean[k] -= eq[k]; | 504 | if (model->voiced) { |
447 | } | 505 | int index = encode_log_Wo(c2const, model->Wo, 6); |
448 | 506 | if (index == 0) { | |
449 | /* two stage VQ */ | 507 | index = 1; |
450 | rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, K, NEWAMP1_VQ_MBEST_DEPTH); | ||
451 | |||
452 | /* running sum of squared error for variance calculation */ | ||
453 | for(k=0; k<K; k++) | ||
454 | *se += pow(rate_K_vec_no_mean[k]-rate_K_vec_no_mean_[k],2.0); | ||
455 | |||
456 | /* scalar quantise mean (effectively the frame energy) */ | ||
457 | float w[1] = {1.0}; | ||
458 | float se_mean; | ||
459 | indexes[2] = quantise(newamp1_energy_cb[0].cb, | ||
460 | mean, | ||
461 | w, | ||
462 | newamp1_energy_cb[0].k, | ||
463 | newamp1_energy_cb[0].m, | ||
464 | &se_mean); | ||
465 | |||
466 | /* scalar quantise Wo. We steal the smallest Wo index to signal | ||
467 | an unvoiced frame */ | ||
468 | if (model->voiced) { | ||
469 | int index = encode_log_Wo(c2const, model->Wo, 6); | ||
470 | if (index == 0) { | ||
471 | index = 1; | ||
472 | } | ||
473 | indexes[3] = index; | ||
474 | } | ||
475 | else { | ||
476 | indexes[3] = 0; | ||
477 | } | 508 | } |
478 | 509 | indexes[3] = index; | |
479 | } | 510 | } else { |
480 | 511 | indexes[3] = 0; | |
512 | } | ||
513 | } | ||
481 | 514 | ||
482 | /*---------------------------------------------------------------------------*\ | 515 | /*---------------------------------------------------------------------------*\ |
483 | 516 | ||
@@ -487,22 +520,22 @@ void newamp1_model_to_indexes(C2CONST *c2const, | |||
487 | 520 | ||
488 | \*---------------------------------------------------------------------------*/ | 521 | \*---------------------------------------------------------------------------*/ |
489 | 522 | ||
490 | void newamp1_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K) | 523 | void newamp1_interpolate(float interpolated_surface_[], float left_vec[], |
491 | { | 524 | float right_vec[], int K) { |
492 | int i, k; | 525 | int i, k; |
493 | int M = 4; | 526 | int M = 4; |
494 | float c; | 527 | float c; |
495 | 528 | ||
496 | /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */ | 529 | /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */ |
497 | 530 | ||
498 | for(i=0,c=1.0; i<M; i++,c-=1.0/M) { | 531 | for (i = 0, c = 1.0; i < M; i++, c -= 1.0 / M) { |
499 | for(k=0; k<K; k++) { | 532 | for (k = 0; k < K; k++) { |
500 | interpolated_surface_[i*K+k] = left_vec[k]*c + right_vec[k]*(1.0-c); | 533 | interpolated_surface_[i * K + k] = |
501 | } | 534 | left_vec[k] * c + right_vec[k] * (1.0 - c); |
502 | } | 535 | } |
536 | } | ||
503 | } | 537 | } |
504 | 538 | ||
505 | |||
506 | /*---------------------------------------------------------------------------*\ | 539 | /*---------------------------------------------------------------------------*\ |
507 | 540 | ||
508 | FUNCTION....: newamp1_indexes_to_rate_K_vec | 541 | FUNCTION....: newamp1_indexes_to_rate_K_vec |
@@ -514,42 +547,39 @@ void newamp1_interpolate(float interpolated_surface_[], float left_vec[], float | |||
514 | 547 | ||
515 | \*---------------------------------------------------------------------------*/ | 548 | \*---------------------------------------------------------------------------*/ |
516 | 549 | ||
517 | void newamp1_indexes_to_rate_K_vec(float rate_K_vec_[], | 550 | void newamp1_indexes_to_rate_K_vec(float rate_K_vec_[], |
518 | float rate_K_vec_no_mean_[], | 551 | float rate_K_vec_no_mean_[], |
519 | float rate_K_sample_freqs_kHz[], | 552 | float rate_K_sample_freqs_kHz[], int K, |
520 | int K, | 553 | float *mean_, int indexes[], |
521 | float *mean_, | ||
522 | int indexes[], | ||
523 | float user_rate_K_vec_no_mean_[], | 554 | float user_rate_K_vec_no_mean_[], |
524 | int post_filter_en) | 555 | int post_filter_en) { |
525 | { | 556 | int k; |
526 | int k; | 557 | const float *codebook1 = newamp1vq_cb[0].cb; |
527 | const float *codebook1 = newamp1vq_cb[0].cb; | 558 | const float *codebook2 = newamp1vq_cb[1].cb; |
528 | const float *codebook2 = newamp1vq_cb[1].cb; | 559 | int n1 = indexes[0]; |
529 | int n1 = indexes[0]; | 560 | int n2 = indexes[1]; |
530 | int n2 = indexes[1]; | 561 | |
531 | 562 | if (user_rate_K_vec_no_mean_ == NULL) { | |
532 | if (user_rate_K_vec_no_mean_ == NULL) { | 563 | /* normal operation */ |
533 | /* normal operation */ | 564 | for (k = 0; k < K; k++) { |
534 | for(k=0; k<K; k++) { | 565 | rate_K_vec_no_mean_[k] = codebook1[K * n1 + k] + codebook2[K * n2 + k]; |
535 | rate_K_vec_no_mean_[k] = codebook1[K*n1+k] + codebook2[K*n2+k]; | ||
536 | } | ||
537 | } else { | ||
538 | /* for development we can optionally inject the quantised rate K vector here */ | ||
539 | for(k=0; k<K; k++) | ||
540 | rate_K_vec_no_mean_[k] = user_rate_K_vec_no_mean_[k]; | ||
541 | } | 566 | } |
542 | 567 | } else { | |
543 | if (post_filter_en) | 568 | /* for development we can optionally inject the quantised rate K vector here |
544 | post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, 1.5); | 569 | */ |
570 | for (k = 0; k < K; k++) | ||
571 | rate_K_vec_no_mean_[k] = user_rate_K_vec_no_mean_[k]; | ||
572 | } | ||
545 | 573 | ||
546 | *mean_ = newamp1_energy_cb[0].cb[indexes[2]]; | 574 | if (post_filter_en) |
575 | post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, 1.5); | ||
547 | 576 | ||
548 | for(k=0; k<K; k++) { | 577 | *mean_ = newamp1_energy_cb[0].cb[indexes[2]]; |
549 | rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_; | ||
550 | } | ||
551 | } | ||
552 | 578 | ||
579 | for (k = 0; k < K; k++) { | ||
580 | rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_; | ||
581 | } | ||
582 | } | ||
553 | 583 | ||
554 | /*---------------------------------------------------------------------------*\ | 584 | /*---------------------------------------------------------------------------*\ |
555 | 585 | ||
@@ -561,78 +591,66 @@ void newamp1_indexes_to_rate_K_vec(float rate_K_vec_[], | |||
561 | 591 | ||
562 | \*---------------------------------------------------------------------------*/ | 592 | \*---------------------------------------------------------------------------*/ |
563 | 593 | ||
564 | void newamp1_indexes_to_model(C2CONST *c2const, | 594 | void newamp1_indexes_to_model(C2CONST *c2const, MODEL model_[], COMP H[], |
565 | MODEL model_[], | ||
566 | COMP H[], | ||
567 | float *interpolated_surface_, | 595 | float *interpolated_surface_, |
568 | float prev_rate_K_vec_[], | 596 | float prev_rate_K_vec_[], float *Wo_left, |
569 | float *Wo_left, | 597 | int *voicing_left, |
570 | int *voicing_left, | 598 | float rate_K_sample_freqs_kHz[], int K, |
571 | float rate_K_sample_freqs_kHz[], | 599 | codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg, |
572 | int K, | 600 | int indexes[], float user_rate_K_vec_no_mean_[], |
573 | codec2_fft_cfg fwd_cfg, | 601 | int post_filter_en) { |
574 | codec2_fft_cfg inv_cfg, | 602 | float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right; |
575 | int indexes[], | 603 | int voicing_right, k; |
576 | float user_rate_K_vec_no_mean_[], | 604 | int M = 4; |
577 | int post_filter_en) | 605 | |
578 | { | 606 | /* extract latest rate K vector */ |
579 | float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right; | 607 | |
580 | int voicing_right, k; | 608 | newamp1_indexes_to_rate_K_vec(rate_K_vec_, rate_K_vec_no_mean_, |
581 | int M = 4; | 609 | rate_K_sample_freqs_kHz, K, &mean_, indexes, |
582 | 610 | user_rate_K_vec_no_mean_, post_filter_en); | |
583 | /* extract latest rate K vector */ | 611 | |
584 | 612 | /* decode latest Wo and voicing */ | |
585 | newamp1_indexes_to_rate_K_vec(rate_K_vec_, | 613 | |
586 | rate_K_vec_no_mean_, | 614 | if (indexes[3]) { |
587 | rate_K_sample_freqs_kHz, | 615 | Wo_right = decode_log_Wo(c2const, indexes[3], 6); |
588 | K, | 616 | voicing_right = 1; |
589 | &mean_, | 617 | } else { |
590 | indexes, | 618 | Wo_right = 2.0 * M_PI / 100.0; |
591 | user_rate_K_vec_no_mean_, | 619 | voicing_right = 0; |
592 | post_filter_en); | 620 | } |
593 | |||
594 | /* decode latest Wo and voicing */ | ||
595 | |||
596 | if (indexes[3]) { | ||
597 | Wo_right = decode_log_Wo(c2const, indexes[3], 6); | ||
598 | voicing_right = 1; | ||
599 | } | ||
600 | else { | ||
601 | Wo_right = 2.0*M_PI/100.0; | ||
602 | voicing_right = 0; | ||
603 | } | ||
604 | |||
605 | /* interpolate 25Hz rate K vec back to 100Hz */ | ||
606 | 621 | ||
607 | float *left_vec = prev_rate_K_vec_; | 622 | /* interpolate 25Hz rate K vec back to 100Hz */ |
608 | float *right_vec = rate_K_vec_; | ||
609 | newamp1_interpolate(interpolated_surface_, left_vec, right_vec, K); | ||
610 | 623 | ||
611 | /* interpolate 25Hz v and Wo back to 100Hz */ | 624 | float *left_vec = prev_rate_K_vec_; |
625 | float *right_vec = rate_K_vec_; | ||
626 | newamp1_interpolate(interpolated_surface_, left_vec, right_vec, K); | ||
612 | 627 | ||
613 | float aWo_[M]; | 628 | /* interpolate 25Hz v and Wo back to 100Hz */ |
614 | int avoicing_[M], aL_[M], i; | ||
615 | 629 | ||
616 | interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, voicing_right); | 630 | float aWo_[M]; |
631 | int avoicing_[M], aL_[M], i; | ||
617 | 632 | ||
618 | /* back to rate L amplitudes, synthesis phase for each frame */ | 633 | interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, |
634 | voicing_right); | ||
619 | 635 | ||
620 | for(i=0; i<M; i++) { | 636 | /* back to rate L amplitudes, synthesise phase for each frame */ |
621 | model_[i].Wo = aWo_[i]; | ||
622 | model_[i].L = aL_[i]; | ||
623 | model_[i].voiced = avoicing_[i]; | ||
624 | 637 | ||
625 | resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K); | 638 | for (i = 0; i < M; i++) { |
626 | determine_phase(c2const, &H[(MAX_AMP+1)*i], &model_[i], NEWAMP1_PHASE_NFFT, fwd_cfg, inv_cfg); | 639 | model_[i].Wo = aWo_[i]; |
627 | } | 640 | model_[i].L = aL_[i]; |
641 | model_[i].voiced = avoicing_[i]; | ||
628 | 642 | ||
629 | /* update memories for next time */ | 643 | resample_rate_L(c2const, &model_[i], &interpolated_surface_[K * i], |
644 | rate_K_sample_freqs_kHz, K); | ||
645 | determine_phase(c2const, &H[(MAX_AMP + 1) * i], &model_[i], | ||
646 | NEWAMP1_PHASE_NFFT, fwd_cfg, inv_cfg); | ||
647 | } | ||
630 | 648 | ||
631 | for(k=0; k<K; k++) { | 649 | /* update memories for next time */ |
632 | prev_rate_K_vec_[k] = rate_K_vec_[k]; | ||
633 | } | ||
634 | *Wo_left = Wo_right; | ||
635 | *voicing_left = voicing_right; | ||
636 | 650 | ||
651 | for (k = 0; k < K; k++) { | ||
652 | prev_rate_K_vec_[k] = rate_K_vec_[k]; | ||
653 | } | ||
654 | *Wo_left = Wo_right; | ||
655 | *voicing_left = voicing_right; | ||
637 | } | 656 | } |
638 | |||
@@ -30,57 +30,57 @@ | |||
30 | #ifndef __NEWAMP1__ | 30 | #ifndef __NEWAMP1__ |
31 | #define __NEWAMP1__ | 31 | #define __NEWAMP1__ |
32 | 32 | ||
33 | #define NEWAMP1_N_INDEXES 4 /* Number of indexes to pack: vq1, vq2, energy, Wo */ | 33 | #define NEWAMP1_N_INDEXES \ |
34 | #define NEWAMP1_PHASE_NFFT 128 /* size of FFT used for phase synthesis */ | 34 | 4 /* Number of indexes to pack: vq1, vq2, energy, Wo */ |
35 | #define NEWAMP1_K 20 /* rate K vector length */ | 35 | #define NEWAMP1_PHASE_NFFT \ |
36 | 128 /* size of FFT used for phase synthesis */ | ||
37 | #define NEWAMP1_K 20 /* rate K vector length */ | ||
38 | #define NEWAMP1_VQ_MBEST_DEPTH \ | ||
39 | 5 /* how many candidates we keep for each stage of mbest search */ | ||
36 | 40 | ||
37 | #include "codec2_fft.h" | 41 | #include "codec2_fft.h" |
38 | #include "comp.h" | 42 | #include "comp.h" |
39 | 43 | ||
40 | void interp_para(float y[], float xp[], float yp[], int np, float x[], int n); | 44 | void interp_para(float y[], float xp[], float yp[], int np, float x[], int n); |
41 | float ftomel(float fHz); | 45 | float ftomel(float fHz); |
42 | void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, float mel_start, float mel_end); | 46 | void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, |
43 | void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); | 47 | float mel_start, float mel_end); |
44 | float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries); | 48 | void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], |
45 | void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain); | 49 | float rate_K_sample_freqs_kHz[], int K); |
46 | void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2); | 50 | float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, |
47 | void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); | 51 | int mbest_entries); |
48 | void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); | 52 | void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, |
49 | void newamp1_model_to_indexes(C2CONST *c2const, | 53 | float pf_gain); |
50 | int indexes[], | 54 | void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, |
51 | MODEL *model, | 55 | int voicing1, int voicing2); |
52 | float rate_K_vec[], | 56 | void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], |
53 | float rate_K_sample_freqs_kHz[], | 57 | float rate_K_sample_freqs_kHz[], int K); |
54 | int K, | 58 | void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, |
55 | float *mean, | 59 | codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); |
56 | float rate_K_vec_no_mean[], | 60 | void determine_autoc(C2CONST *c2const, float Rk[], int order, MODEL *model, |
57 | float rate_K_vec_no_mean_[], | 61 | int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); |
58 | float *se, | 62 | void newamp1_model_to_indexes(C2CONST *c2const, int indexes[], MODEL *model, |
59 | float *eq, | 63 | float rate_K_vec[], |
60 | int eq_en); | 64 | float rate_K_sample_freqs_kHz[], int K, |
61 | void newamp1_indexes_to_rate_K_vec(float rate_K_vec_[], | 65 | float *mean, float rate_K_vec_no_mean[], |
62 | float rate_K_vec_no_mean_[], | 66 | float rate_K_vec_no_mean_[], float *se, float *eq, |
63 | float rate_K_sample_freqs_kHz[], | 67 | int eq_en); |
64 | int K, | 68 | void newamp1_indexes_to_rate_K_vec(float rate_K_vec_[], |
65 | float *mean_, | 69 | float rate_K_vec_no_mean_[], |
66 | int indexes[], | 70 | float rate_K_sample_freqs_kHz[], int K, |
71 | float *mean_, int indexes[], | ||
67 | float user_rate_K_vec_no_mean_[], | 72 | float user_rate_K_vec_no_mean_[], |
68 | int post_filter_en); | 73 | int post_filter_en); |
69 | void newamp1_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K); | 74 | void newamp1_interpolate(float interpolated_surface_[], float left_vec[], |
70 | 75 | float right_vec[], int K); | |
71 | void newamp1_indexes_to_model(C2CONST *c2const, | 76 | void newamp1_eq(float rate_K_vec_no_mean[], float eq[], int K, int eq_en); |
72 | MODEL model_[], | 77 | void newamp1_indexes_to_model(C2CONST *c2const, MODEL model_[], COMP H[], |
73 | COMP H[], | 78 | float interpolated_surface_[], |
74 | float interpolated_surface_[], | 79 | float prev_rate_K_vec_[], float *Wo_left, |
75 | float prev_rate_K_vec_[], | 80 | int *voicing_left, |
76 | float *Wo_left, | 81 | float rate_K_sample_freqs_kHz[], int K, |
77 | int *voicing_left, | 82 | codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg, |
78 | float rate_K_sample_freqs_kHz[], | 83 | int indexes[], float user_rate_K_vec_no_mean_[], |
79 | int K, | ||
80 | codec2_fft_cfg fwd_cfg, | ||
81 | codec2_fft_cfg inv_cfg, | ||
82 | int indexes[], | ||
83 | float user_rate_K_vec_no_mean_[], | ||
84 | int post_filter_en); | 84 | int post_filter_en); |
85 | 85 | ||
86 | #endif | 86 | #endif |
diff --git a/newamp2.c b/newamp2.c deleted file mode 100644 index 6550557..0000000 --- a/newamp2.c +++ /dev/null | |||
@@ -1,570 +0,0 @@ | |||
1 | /*---------------------------------------------------------------------------*\ | ||
2 | |||
3 | FILE........: newamp2.c | ||
4 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
5 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
6 | DATE CREATED: July 2018 | ||
7 | BASED ON....: "newamp1" by David Rowe | ||
8 | |||
9 | Quantisation functions for the sinusoidal coder, using "newamp1" | ||
10 | algorithm that resamples variable rate L [Am} to a fixed rate K then | ||
11 | VQs. | ||
12 | |||
13 | \*---------------------------------------------------------------------------*/ | ||
14 | |||
15 | /* | ||
16 | Copyright David Rowe 2017 | ||
17 | |||
18 | All rights reserved. | ||
19 | |||
20 | This program is free software; you can redistribute it and/or modify | ||
21 | it under the terms of the GNU Lesser General Public License version 2.1, as | ||
22 | published by the Free Software Foundation. This program is | ||
23 | distributed in the hope that it will be useful, but WITHOUT ANY | ||
24 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
25 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||
26 | License for more details. | ||
27 | |||
28 | You should have received a copy of the GNU Lesser General Public License | ||
29 | along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
30 | |||
31 | */ | ||
32 | |||
33 | #include <assert.h> | ||
34 | #include <stdio.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <string.h> | ||
37 | #include <math.h> | ||
38 | |||
39 | #include "defines.h" | ||
40 | #include "phase.h" | ||
41 | #include "quantise.h" | ||
42 | #include "mbest.h" | ||
43 | #include "newamp1.h" | ||
44 | #include "newamp2.h" | ||
45 | |||
46 | /*---------------------------------------------------------------------------*\ | ||
47 | |||
48 | FUNCTION....: n2_mel_sample_freqs_kHz() | ||
49 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
50 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
51 | DATE CREATED: July 2018 | ||
52 | |||
53 | Outputs fixed frequencies for the K-Vectors to be able to work with both 8k and 16k mode. | ||
54 | |||
55 | \*---------------------------------------------------------------------------*/ | ||
56 | |||
57 | void n2_mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K) | ||
58 | { | ||
59 | float freq[] = {0.199816, 0.252849, 0.309008, 0.368476, 0.431449, 0.498134, 0.568749, 0.643526, 0.722710, 0.806561, 0.895354, 0.989380, | ||
60 | 1.088948, 1.194384, 1.306034, 1.424264, 1.549463, 1.682041, 1.822432, 1.971098, 2.128525, 2.295232, 2.471763, 2.658699, | ||
61 | 2.856652, 3.066272, 3.288246, 3.523303, 3.772214, 4.035795, 4.314912, 4.610478, 4.923465, 5.254899, 5.605865, 5.977518, | ||
62 | 6.371075, 6.787827, 7.229141, 7.696465}; | ||
63 | int k; | ||
64 | //printf("\n\n"); | ||
65 | for (k=0; k<K; k++) { | ||
66 | rate_K_sample_freqs_kHz[k] = freq[k]; | ||
67 | // printf("%f ",mel); | ||
68 | // printf("%f \n",rate_K_sample_freqs_kHz[k]); | ||
69 | } | ||
70 | |||
71 | } | ||
72 | |||
73 | |||
74 | /*---------------------------------------------------------------------------*\ | ||
75 | |||
76 | FUNCTION....: n2_resample_const_rate_f() still equal to resample_const_rate_f() | ||
77 | AUTHOR......: David Rowe | ||
78 | DATE CREATED: Jan 2017 | ||
79 | |||
80 | Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K. | ||
81 | |||
82 | \*---------------------------------------------------------------------------*/ | ||
83 | |||
84 | void n2_resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K) | ||
85 | { | ||
86 | int m; | ||
87 | float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1], AmdB_peak; | ||
88 | |||
89 | /* convert rate L=pi/Wo amplitude samples to fixed rate K */ | ||
90 | |||
91 | AmdB_peak = -100.0; | ||
92 | for(m=1; m<=model->L; m++) { | ||
93 | AmdB[m] = 20.0*log10(model->A[m]+1E-16); | ||
94 | if (AmdB[m] > AmdB_peak) { | ||
95 | AmdB_peak = AmdB[m]; | ||
96 | } | ||
97 | rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI; | ||
98 | //printf("m: %d AmdB: %f AmdB_peak: %f sf: %f\n", m, AmdB[m], AmdB_peak, rate_L_sample_freqs_kHz[m]); | ||
99 | } | ||
100 | |||
101 | /* clip between peak and peak -50dB, to reduce dynamic range */ | ||
102 | |||
103 | for(m=1; m<=model->L; m++) { | ||
104 | if (AmdB[m] < (AmdB_peak-50.0)) { | ||
105 | AmdB[m] = AmdB_peak-50.0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, rate_K_sample_freqs_kHz, K); | ||
110 | } | ||
111 | |||
112 | |||
113 | /*---------------------------------------------------------------------------*\ | ||
114 | |||
115 | FUNCTION....: n2_rate_K_mbest_encode | ||
116 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
117 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
118 | DATE CREATED: July 2018 | ||
119 | |||
120 | One stage rate K newamp2 VQ quantiser using mbest search. | ||
121 | |||
122 | \*---------------------------------------------------------------------------*/ | ||
123 | |||
124 | void n2_rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim) | ||
125 | { | ||
126 | int i, n1; | ||
127 | const float *codebook1 = newamp2vq_cb[0].cb; | ||
128 | struct MBEST *mbest_stage1; | ||
129 | float w[ndim]; | ||
130 | int index[1]; | ||
131 | |||
132 | /* codebook is compiled for a fixed K */ | ||
133 | |||
134 | //assert(ndim == newamp2vq_cb[0].k); | ||
135 | |||
136 | /* equal weights, could be argued mel freq axis gives freq dep weighting */ | ||
137 | |||
138 | for(i=0; i<ndim; i++) | ||
139 | w[i] = 1.0; | ||
140 | |||
141 | mbest_stage1 = mbest_create(1); | ||
142 | |||
143 | index[0] = 0; | ||
144 | |||
145 | /* Stage 1 */ | ||
146 | |||
147 | mbest_search450(codebook1, x, w, ndim,NEWAMP2_K, newamp2vq_cb[0].m, mbest_stage1, index); | ||
148 | MBEST_PRINT("Stage 1:", mbest_stage1); | ||
149 | n1 = mbest_stage1->list[0].index[0]; | ||
150 | |||
151 | mbest_destroy(mbest_stage1); | ||
152 | |||
153 | //indexes[1]: legacy from newamp1 | ||
154 | indexes[0] = n1; indexes[1] = n1; | ||
155 | |||
156 | } | ||
157 | |||
158 | |||
159 | /*---------------------------------------------------------------------------*\ | ||
160 | |||
161 | FUNCTION....: n2_resample_rate_L | ||
162 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
163 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
164 | DATE CREATED: July 2018 | ||
165 | |||
166 | Decoder side conversion of rate K vector back to rate L. | ||
167 | Plosives are set to zero for the first 2 of 4 frames. | ||
168 | |||
169 | \*---------------------------------------------------------------------------*/ | ||
170 | |||
171 | void n2_resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K,int plosive_flag) | ||
172 | { | ||
173 | float rate_K_vec_term[K+2], rate_K_sample_freqs_kHz_term[K+2]; | ||
174 | float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1]; | ||
175 | int m,k; | ||
176 | |||
177 | /* terminate either end of the rate K vecs with 0dB points */ | ||
178 | |||
179 | rate_K_vec_term[0] = rate_K_vec_term[K+1] = 0.0; | ||
180 | rate_K_sample_freqs_kHz_term[0] = 0.0; | ||
181 | rate_K_sample_freqs_kHz_term[K+1] = 4.0; | ||
182 | |||
183 | for(k=0; k<K; k++) { | ||
184 | rate_K_vec_term[k+1] = rate_K_vec[k]; | ||
185 | rate_K_sample_freqs_kHz_term[k+1] = rate_K_sample_freqs_kHz[k]; | ||
186 | |||
187 | //printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], rate_K_vec[k]); | ||
188 | } | ||
189 | |||
190 | for(m=1; m<=model->L; m++) { | ||
191 | rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI; | ||
192 | } | ||
193 | |||
194 | interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K+2, &rate_L_sample_freqs_kHz[1], model->L); | ||
195 | for(m=1; m<=model->L; m++) { | ||
196 | if(plosive_flag==0){ | ||
197 | model->A[m] = pow(10.0, AmdB[m]/20.0); | ||
198 | }else{ | ||
199 | model->A[m] = 0.1; | ||
200 | } | ||
201 | // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /*---------------------------------------------------------------------------*\ | ||
206 | |||
207 | FUNCTION....: n2_post_filter_newamp2 | ||
208 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
209 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
210 | DATE CREATED: July 2018 | ||
211 | |||
212 | Postfilter for the pseudo wideband mode. Still has to be adapted! | ||
213 | |||
214 | \*---------------------------------------------------------------------------*/ | ||
215 | |||
216 | void n2_post_filter_newamp2(float vec[], float sample_freq_kHz[], int K, float pf_gain) | ||
217 | { | ||
218 | int k; | ||
219 | |||
220 | /* | ||
221 | vec is rate K vector describing spectrum of current frame lets | ||
222 | pre-emp before applying PF. 20dB/dec over 300Hz. Postfilter | ||
223 | affects energy of frame so we measure energy before and after | ||
224 | and normalise. Plenty of room for experiment here as well. | ||
225 | */ | ||
226 | |||
227 | float pre[K]; | ||
228 | float e_before = 0.0; | ||
229 | float e_after = 0.0; | ||
230 | for(k=0; k<K; k++) { | ||
231 | pre[k] = 20.0*log10f(sample_freq_kHz[k]/0.3); | ||
232 | vec[k] += pre[k]; | ||
233 | e_before += POW10F(vec[k]/10.0); | ||
234 | vec[k] *= pf_gain; | ||
235 | e_after += POW10F(vec[k]/10.0); | ||
236 | } | ||
237 | |||
238 | float gain = e_after/e_before; | ||
239 | float gaindB = 10*log10f(gain); | ||
240 | |||
241 | for(k=0; k<K; k++) { | ||
242 | vec[k] -= gaindB; | ||
243 | vec[k] -= pre[k]; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | |||
248 | /*---------------------------------------------------------------------------*\ | ||
249 | |||
250 | FUNCTION....: newamp2_model_to_indexes | ||
251 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
252 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
253 | DATE CREATED: July 2018 | ||
254 | |||
255 | newamp2 encoder: Encodes the 8k sampled samples using mbest search (one stage) | ||
256 | |||
257 | \*---------------------------------------------------------------------------*/ | ||
258 | |||
259 | void newamp2_model_to_indexes(C2CONST *c2const, | ||
260 | int indexes[], | ||
261 | MODEL *model, | ||
262 | float rate_K_vec[], | ||
263 | float rate_K_sample_freqs_kHz[], | ||
264 | int K, | ||
265 | float *mean, | ||
266 | float rate_K_vec_no_mean[], | ||
267 | float rate_K_vec_no_mean_[], | ||
268 | int plosive | ||
269 | ) | ||
270 | { | ||
271 | int k; | ||
272 | |||
273 | /* convert variable rate L to fixed rate K */ | ||
274 | |||
275 | resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K); | ||
276 | |||
277 | /* remove mean and two stage VQ */ | ||
278 | |||
279 | float sum = 0.0; | ||
280 | for(k=0; k<K; k++) | ||
281 | sum += rate_K_vec[k]; | ||
282 | *mean = sum/K; | ||
283 | for(k=0; k<K; k++) | ||
284 | { | ||
285 | rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean; | ||
286 | } | ||
287 | //NEWAMP2_16K_K+1 because the last vector is not a vector for VQ (and not included in the constant) | ||
288 | //but a calculated medium mean value | ||
289 | n2_rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, NEWAMP2_16K_K+1); | ||
290 | |||
291 | /* scalar quantise mean (effectively the frame energy) */ | ||
292 | |||
293 | float w[1] = {1.0}; | ||
294 | float se; | ||
295 | indexes[2] = quantise(newamp2_energy_cb[0].cb, | ||
296 | mean, | ||
297 | w, | ||
298 | newamp2_energy_cb[0].k, | ||
299 | newamp2_energy_cb[0].m, | ||
300 | &se); | ||
301 | |||
302 | /* scalar quantise Wo. We steal the smallest Wo index to signal | ||
303 | an unvoiced frame */ | ||
304 | |||
305 | if (model->voiced) { | ||
306 | int index = encode_log_Wo(c2const, model->Wo, 6); | ||
307 | if (index == 0) { | ||
308 | index = 1; | ||
309 | } | ||
310 | if (index == 63) { | ||
311 | index = 62; | ||
312 | } | ||
313 | indexes[3] = index; | ||
314 | } | ||
315 | else { | ||
316 | indexes[3] = 0; | ||
317 | } | ||
318 | if(plosive != 0){ | ||
319 | indexes[3] = 63; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | |||
324 | /*---------------------------------------------------------------------------*\ | ||
325 | |||
326 | FUNCTION....: newamp2_indexes_to_rate_K_vec | ||
327 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
328 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
329 | DATE CREATED: July 2018 | ||
330 | |||
331 | newamp2 decoder for amplitudes {Am}. Given the rate K VQ and energy | ||
332 | indexes, outputs rate K vector. Equal to newamp1 but using only one stage VQ. | ||
333 | |||
334 | \*---------------------------------------------------------------------------*/ | ||
335 | |||
336 | void newamp2_indexes_to_rate_K_vec(float rate_K_vec_[], | ||
337 | float rate_K_vec_no_mean_[], | ||
338 | float rate_K_sample_freqs_kHz[], | ||
339 | int K, | ||
340 | float *mean_, | ||
341 | int indexes[], | ||
342 | float pf_gain) | ||
343 | { | ||
344 | int k; | ||
345 | const float *codebook1 = newamp2vq_cb[0].cb; | ||
346 | int n1 = indexes[0]; | ||
347 | |||
348 | for(k=0; k<K; k++) { | ||
349 | rate_K_vec_no_mean_[k] = codebook1[(NEWAMP2_16K_K+1)*n1+k]; | ||
350 | } | ||
351 | |||
352 | post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain); | ||
353 | |||
354 | *mean_ = newamp2_energy_cb[0].cb[indexes[2]]; | ||
355 | |||
356 | for(k=0; k<K; k++) { | ||
357 | rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_; | ||
358 | } | ||
359 | } | ||
360 | |||
361 | /*---------------------------------------------------------------------------*\ | ||
362 | |||
363 | FUNCTION....: newamp2_16k_indexes_to_rate_K_vec | ||
364 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
365 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
366 | DATE CREATED: July 2018 | ||
367 | |||
368 | newamp2 decoder for amplitudes {Am}. Given the rate K VQ and energy | ||
369 | indexes, outputs rate K vector. Extends the sample rate by looking up the corresponding | ||
370 | higher frequency values with their energy difference to the base energy (=>mean2) | ||
371 | |||
372 | \*---------------------------------------------------------------------------*/ | ||
373 | |||
374 | void newamp2_16k_indexes_to_rate_K_vec(float rate_K_vec_[], | ||
375 | float rate_K_vec_no_mean_[], | ||
376 | float rate_K_sample_freqs_kHz[], | ||
377 | int K, | ||
378 | float *mean_, | ||
379 | int indexes[], | ||
380 | float pf_gain) | ||
381 | { | ||
382 | int k; | ||
383 | const float *codebook1 = newamp2vq_cb[0].cb; | ||
384 | float mean2 = 0; | ||
385 | int n1 = indexes[0]; | ||
386 | |||
387 | for(k=0; k<K; k++) { | ||
388 | rate_K_vec_no_mean_[k] = codebook1[(K+1)*n1+k]; | ||
389 | } | ||
390 | |||
391 | n2_post_filter_newamp2(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain); | ||
392 | |||
393 | *mean_ = newamp2_energy_cb[0].cb[indexes[2]]; | ||
394 | mean2 = *mean_ + codebook1[(K+1)*n1+K] -10; | ||
395 | |||
396 | //HF ear Protection | ||
397 | if(mean2>50){ | ||
398 | mean2 = 50; | ||
399 | } | ||
400 | |||
401 | for(k=0; k<K; k++) { | ||
402 | if(k<NEWAMP2_K){ | ||
403 | rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_; | ||
404 | } | ||
405 | else{ | ||
406 | //Amplify or Reduce ?? | ||
407 | rate_K_vec_[k] = rate_K_vec_no_mean_[k] + mean2; | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | /*---------------------------------------------------------------------------*\ | ||
412 | |||
413 | FUNCTION....: newamp2_interpolate | ||
414 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
415 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
416 | DATE CREATED: July 2018 | ||
417 | |||
418 | Interpolates to the 4 10ms Frames and leaves the forst 2 empty for plosives | ||
419 | |||
420 | \*---------------------------------------------------------------------------*/ | ||
421 | |||
422 | void newamp2_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K, int plosive_flag) | ||
423 | { | ||
424 | int i, k; | ||
425 | int M = 4; | ||
426 | float c; | ||
427 | |||
428 | /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */ | ||
429 | |||
430 | if(plosive_flag == 0){ | ||
431 | for(i=0,c=1.0; i<M; i++,c-=1.0/M) { | ||
432 | for(k=0; k<K; k++) { | ||
433 | interpolated_surface_[i*K+k] = left_vec[k]*c + right_vec[k]*(1.0-c); | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | else{ | ||
438 | for(i=0,c=1.0; i<M; i++,c-=1.0/M) { | ||
439 | for(k=0; k<K; k++) { | ||
440 | if(i<2){ | ||
441 | interpolated_surface_[i*K+k] = 0; | ||
442 | } | ||
443 | else{ | ||
444 | //perhaps add some dB ? | ||
445 | interpolated_surface_[i*K+k] = right_vec[k]; | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | } | ||
451 | } | ||
452 | |||
453 | |||
454 | /*---------------------------------------------------------------------------*\ | ||
455 | |||
456 | FUNCTION....: newamp2_indexes_to_model | ||
457 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
458 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
459 | DATE CREATED: July 2018 | ||
460 | |||
461 | newamp2 decoder. Chooses whether to decode to 16k mode or to 8k mode | ||
462 | |||
463 | \*---------------------------------------------------------------------------*/ | ||
464 | |||
465 | void newamp2_indexes_to_model(C2CONST *c2const, | ||
466 | MODEL model_[], | ||
467 | COMP H[], | ||
468 | float *interpolated_surface_, | ||
469 | float prev_rate_K_vec_[], | ||
470 | float *Wo_left, | ||
471 | int *voicing_left, | ||
472 | float rate_K_sample_freqs_kHz[], | ||
473 | int K, | ||
474 | codec2_fft_cfg fwd_cfg, | ||
475 | codec2_fft_cfg inv_cfg, | ||
476 | int indexes[], | ||
477 | float pf_gain, | ||
478 | int flag16k) | ||
479 | { | ||
480 | float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right; | ||
481 | int voicing_right, k; | ||
482 | int M = 4; | ||
483 | |||
484 | /* extract latest rate K vector */ | ||
485 | |||
486 | if(flag16k == 0){ | ||
487 | newamp2_indexes_to_rate_K_vec(rate_K_vec_, | ||
488 | rate_K_vec_no_mean_, | ||
489 | rate_K_sample_freqs_kHz, | ||
490 | K, | ||
491 | &mean_, | ||
492 | indexes, | ||
493 | pf_gain); | ||
494 | }else{ | ||
495 | newamp2_16k_indexes_to_rate_K_vec(rate_K_vec_, | ||
496 | rate_K_vec_no_mean_, | ||
497 | rate_K_sample_freqs_kHz, | ||
498 | K, | ||
499 | &mean_, | ||
500 | indexes, | ||
501 | pf_gain); | ||
502 | } | ||
503 | |||
504 | |||
505 | /* decode latest Wo and voicing and plosive */ | ||
506 | int plosive_flag = 0; | ||
507 | |||
508 | //Voiced with Wo | ||
509 | if (indexes[3]>0 && indexes[3]<63) { | ||
510 | Wo_right = decode_log_Wo(c2const, indexes[3], 6); | ||
511 | voicing_right = 1; | ||
512 | } | ||
513 | //Unvoiced | ||
514 | else if(indexes[3] == 0){ | ||
515 | Wo_right = 2.0*M_PI/100.0; | ||
516 | voicing_right = 0; | ||
517 | } | ||
518 | //indexes[3]=63 (= Plosive) and unvoiced | ||
519 | else { | ||
520 | Wo_right = 2.0*M_PI/100.0; | ||
521 | voicing_right = 0; | ||
522 | plosive_flag = 1; | ||
523 | } | ||
524 | |||
525 | /* interpolate 25Hz rate K vec back to 100Hz */ | ||
526 | |||
527 | float *left_vec = prev_rate_K_vec_; | ||
528 | float *right_vec = rate_K_vec_; | ||
529 | newamp2_interpolate(interpolated_surface_, left_vec, right_vec, K,plosive_flag); | ||
530 | |||
531 | /* interpolate 25Hz v and Wo back to 100Hz */ | ||
532 | |||
533 | float aWo_[M]; | ||
534 | int avoicing_[M], aL_[M], i; | ||
535 | |||
536 | interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, voicing_right); | ||
537 | |||
538 | /* back to rate L amplitudes, synthesis phase for each frame */ | ||
539 | |||
540 | for(i=0; i<M; i++) { | ||
541 | model_[i].Wo = aWo_[i]; | ||
542 | model_[i].L = aL_[i]; | ||
543 | model_[i].voiced = avoicing_[i]; | ||
544 | //Plosive Detected | ||
545 | if(plosive_flag>0){ | ||
546 | //First two frames are set to zero | ||
547 | if (i<2){ | ||
548 | n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,1); | ||
549 | } | ||
550 | else{ | ||
551 | n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,0); | ||
552 | } | ||
553 | } | ||
554 | //No Plosive, standard resample | ||
555 | else{ | ||
556 | n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,0); | ||
557 | } | ||
558 | determine_phase(c2const, &H[(MAX_AMP+1)*i], &model_[i], NEWAMP2_PHASE_NFFT, fwd_cfg, inv_cfg); | ||
559 | } | ||
560 | |||
561 | /* update memories for next time */ | ||
562 | |||
563 | for(k=0; k<K; k++) { | ||
564 | prev_rate_K_vec_[k] = rate_K_vec_[k]; | ||
565 | } | ||
566 | *Wo_left = Wo_right; | ||
567 | *voicing_left = voicing_right; | ||
568 | |||
569 | } | ||
570 | |||
diff --git a/newamp2.h b/newamp2.h deleted file mode 100644 index ec14566..0000000 --- a/newamp2.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | /*---------------------------------------------------------------------------*\ | ||
2 | |||
3 | FILE........: newamp2.h | ||
4 | AUTHOR......: Thomas Kurin and Stefan Erhardt | ||
5 | INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg | ||
6 | DATE CREATED: July 2018 | ||
7 | BASED ON....: "newamp1.h" by David Rowe | ||
8 | |||
9 | Quantisation functions for the sinusoidal coder, using "newamp1" | ||
10 | algorithm that resamples variable rate L [Am} to a fixed rate K then | ||
11 | VQs. | ||
12 | |||
13 | \*---------------------------------------------------------------------------*/ | ||
14 | |||
15 | /* | ||
16 | Copyright Thomas Kurin and Stefan Erhardt 2018 | ||
17 | |||
18 | All rights reserved. | ||
19 | |||
20 | This program is free software; you can redistribute it and/or modify | ||
21 | it under the terms of the GNU Lesser General Public License version 2.1, as | ||
22 | published by the Free Software Foundation. This program is | ||
23 | distributed in the hope that it will be useful, but WITHOUT ANY | ||
24 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
25 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||
26 | License for more details. | ||
27 | |||
28 | You should have received a copy of the GNU Lesser General Public License | ||
29 | along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
30 | */ | ||
31 | |||
32 | #ifndef __NEWAMP2__ | ||
33 | #define __NEWAMP2__ | ||
34 | |||
35 | #define NEWAMP2_N_INDEXES 4 /* Number of indexes to pack: vq1, vq2, energy, Wo */ | ||
36 | #define NEWAMP2_PHASE_NFFT 128 /* size of FFT used for phase synthesis */ | ||
37 | #define NEWAMP2_K 29 /* rate K vector length */ | ||
38 | #define NEWAMP2_16K_K 40 /* rate K vector length for 16k Mode */ | ||
39 | |||
40 | #include "codec2_fft.h" | ||
41 | #include "comp.h" | ||
42 | |||
43 | void n2_mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K); | ||
44 | void n2_resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K); | ||
45 | void n2_rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim); | ||
46 | void n2_resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K,int plosive_flag); | ||
47 | void n2_post_filter_newamp2(float vec[], float sample_freq_kHz[], int K, float pf_gain); | ||
48 | void newamp2_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K,int plosive_flag); | ||
49 | void newamp2_model_to_indexes(C2CONST *c2const, | ||
50 | int indexes[], | ||
51 | MODEL *model, | ||
52 | float rate_K_vec[], | ||
53 | float rate_K_sample_freqs_kHz[], | ||
54 | int K, | ||
55 | float *mean, | ||
56 | float rate_K_vec_no_mean[], | ||
57 | float rate_K_vec_no_mean_[], | ||
58 | int plosiv | ||
59 | ); | ||
60 | void newamp2_indexes_to_rate_K_vec(float rate_K_vec_[], | ||
61 | float rate_K_vec_no_mean_[], | ||
62 | float rate_K_sample_freqs_kHz[], | ||
63 | int K, | ||
64 | float *mean_, | ||
65 | int indexes[], | ||
66 | float pf_gain); | ||
67 | void newamp2_16k_indexes_to_rate_K_vec(float rate_K_vec_[], | ||
68 | float rate_K_vec_no_mean_[], | ||
69 | float rate_K_sample_freqs_kHz[], | ||
70 | int K, | ||
71 | float *mean_, | ||
72 | int indexes[], | ||
73 | float pf_gain); | ||
74 | void newamp2_indexes_to_model(C2CONST *c2const, | ||
75 | MODEL model_[], | ||
76 | COMP H[], | ||
77 | float interpolated_surface_[], | ||
78 | float prev_rate_K_vec_[], | ||
79 | float *Wo_left, | ||
80 | int *voicing_left, | ||
81 | float rate_K_sample_freqs_kHz[], | ||
82 | int K, | ||
83 | codec2_fft_cfg fwd_cfg, | ||
84 | codec2_fft_cfg inv_cfg, | ||
85 | int indexes[], | ||
86 | float pf_gain, | ||
87 | int flag16k); | ||
88 | |||
89 | #endif | ||
@@ -25,115 +25,79 @@ | |||
25 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 25 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "defines.h" | ||
29 | #include "nlp.h" | 28 | #include "nlp.h" |
30 | #include "dump.h" | 29 | |
31 | #include "codec2_fft.h" | 30 | #include "codec2_fft.h" |
31 | #include "defines.h" | ||
32 | #include "dump.h" | ||
32 | #undef PROFILE | 33 | #undef PROFILE |
33 | #include "machdep.h" | ||
34 | #include "os.h" | ||
35 | |||
36 | #include <assert.h> | 34 | #include <assert.h> |
37 | #include <math.h> | 35 | #include <math.h> |
38 | #include <stdlib.h> | 36 | #include <stdlib.h> |
39 | 37 | ||
38 | #include "machdep.h" | ||
39 | #include "os.h" | ||
40 | |||
40 | /*---------------------------------------------------------------------------*\ | 41 | /*---------------------------------------------------------------------------*\ |
41 | 42 | ||
42 | DEFINES | 43 | DEFINES |
43 | 44 | ||
44 | \*---------------------------------------------------------------------------*/ | 45 | \*---------------------------------------------------------------------------*/ |
45 | 46 | ||
46 | #define PMAX_M 320 /* maximum NLP analysis window size */ | 47 | #define PMAX_M 320 /* maximum NLP analysis window size */ |
47 | #define COEFF 0.95 /* notch filter parameter */ | 48 | #define COEFF 0.95 /* notch filter parameter */ |
48 | #define PE_FFT_SIZE 512 /* DFT size for pitch estimation */ | 49 | #define PE_FFT_SIZE 512 /* DFT size for pitch estimation */ |
49 | #define DEC 5 /* decimation factor */ | 50 | #define DEC 5 /* decimation factor */ |
50 | #define SAMPLE_RATE 8000 | 51 | #define SAMPLE_RATE 8000 |
51 | #define PI 3.141592654 /* mathematical constant */ | 52 | #define PI 3.141592654 /* mathematical constant */ |
52 | #define T 0.1 /* threshold for local minima candidate */ | 53 | #define T 0.1 /* threshold for local minima candidate */ |
53 | #define F0_MAX 500 | 54 | #define F0_MAX 500 |
54 | #define CNLP 0.3 /* post processor constant */ | 55 | #define CNLP 0.3 /* post processor constant */ |
55 | #define NLP_NTAP 48 /* Decimation LPF order */ | 56 | #define NLP_NTAP 48 /* Decimation LPF order */ |
56 | 57 | ||
57 | /* 8 to 16 kHz sample rate conversion */ | 58 | /* 8 to 16 kHz sample rate conversion */ |
58 | 59 | ||
59 | #define FDMDV_OS 2 /* oversampling rate */ | 60 | #define FDMDV_OS 2 /* oversampling rate */ |
60 | #define FDMDV_OS_TAPS_16K 48 /* number of OS filter taps at 16kHz */ | 61 | #define FDMDV_OS_TAPS_16K 48 /* number of OS filter taps at 16kHz */ |
61 | #define FDMDV_OS_TAPS_8K (FDMDV_OS_TAPS_16K/FDMDV_OS) /* number of OS filter taps at 8kHz */ | 62 | #define FDMDV_OS_TAPS_8K \ |
63 | (FDMDV_OS_TAPS_16K / FDMDV_OS) /* number of OS filter taps at 8kHz */ | ||
62 | 64 | ||
63 | /*---------------------------------------------------------------------------*\ | 65 | /*---------------------------------------------------------------------------*\ |
64 | 66 | ||
65 | GLOBALS | 67 | GLOBALS |
66 | 68 | ||
67 | \*---------------------------------------------------------------------------*/ | 69 | \*---------------------------------------------------------------------------*/ |
68 | 70 | ||
69 | /* 48 tap 600Hz low pass FIR filter coefficients */ | 71 | /* 48 tap 600Hz low pass FIR filter coefficients */ |
70 | 72 | ||
71 | const float nlp_fir[] = { | 73 | const float nlp_fir[] = { |
72 | -1.0818124e-03, | 74 | -1.0818124e-03, -1.1008344e-03, -9.2768838e-04, -4.2289438e-04, |
73 | -1.1008344e-03, | 75 | 5.5034190e-04, 2.0029849e-03, 3.7058509e-03, 5.1449415e-03, |
74 | -9.2768838e-04, | 76 | 5.5924666e-03, 4.3036754e-03, 8.0284511e-04, -4.8204610e-03, |
75 | -4.2289438e-04, | 77 | -1.1705810e-02, -1.8199275e-02, -2.2065282e-02, -2.0920610e-02, |
76 | 5.5034190e-04, | 78 | -1.2808831e-02, 3.2204775e-03, 2.6683811e-02, 5.5520624e-02, |
77 | 2.0029849e-03, | 79 | 8.6305944e-02, 1.1480192e-01, 1.3674206e-01, 1.4867556e-01, |
78 | 3.7058509e-03, | 80 | 1.4867556e-01, 1.3674206e-01, 1.1480192e-01, 8.6305944e-02, |
79 | 5.1449415e-03, | 81 | 5.5520624e-02, 2.6683811e-02, 3.2204775e-03, -1.2808831e-02, |
80 | 5.5924666e-03, | 82 | -2.0920610e-02, -2.2065282e-02, -1.8199275e-02, -1.1705810e-02, |
81 | 4.3036754e-03, | 83 | -4.8204610e-03, 8.0284511e-04, 4.3036754e-03, 5.5924666e-03, |
82 | 8.0284511e-04, | 84 | 5.1449415e-03, 3.7058509e-03, 2.0029849e-03, 5.5034190e-04, |
83 | -4.8204610e-03, | 85 | -4.2289438e-04, -9.2768838e-04, -1.1008344e-03, -1.0818124e-03}; |
84 | -1.1705810e-02, | ||
85 | -1.8199275e-02, | ||
86 | -2.2065282e-02, | ||
87 | -2.0920610e-02, | ||
88 | -1.2808831e-02, | ||
89 | 3.2204775e-03, | ||
90 | 2.6683811e-02, | ||
91 | 5.5520624e-02, | ||
92 | 8.6305944e-02, | ||
93 | 1.1480192e-01, | ||
94 | 1.3674206e-01, | ||
95 | 1.4867556e-01, | ||
96 | 1.4867556e-01, | ||
97 | 1.3674206e-01, | ||
98 | 1.1480192e-01, | ||
99 | 8.6305944e-02, | ||
100 | 5.5520624e-02, | ||
101 | 2.6683811e-02, | ||
102 | 3.2204775e-03, | ||
103 | -1.2808831e-02, | ||
104 | -2.0920610e-02, | ||
105 | -2.2065282e-02, | ||
106 | -1.8199275e-02, | ||
107 | -1.1705810e-02, | ||
108 | -4.8204610e-03, | ||
109 | 8.0284511e-04, | ||
110 | 4.3036754e-03, | ||
111 | 5.5924666e-03, | ||
112 | 5.1449415e-03, | ||
113 | 3.7058509e-03, | ||
114 | 2.0029849e-03, | ||
115 | 5.5034190e-04, | ||
116 | -4.2289438e-04, | ||
117 | -9.2768838e-04, | ||
118 | -1.1008344e-03, | ||
119 | -1.0818124e-03 | ||
120 | }; | ||
121 | 86 | ||
122 | typedef struct { | 87 | typedef struct { |
123 | int Fs; /* sample rate in Hz */ | 88 | int Fs; /* sample rate in Hz */ |
124 | int m; | 89 | int m; |
125 | float w[PMAX_M/DEC]; /* DFT window */ | 90 | float w[PMAX_M / DEC]; /* DFT window */ |
126 | float sq[PMAX_M]; /* squared speech samples */ | 91 | float sq[PMAX_M]; /* squared speech samples */ |
127 | float mem_x,mem_y; /* memory for notch filter */ | 92 | float mem_x, mem_y; /* memory for notch filter */ |
128 | float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */ | 93 | float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */ |
129 | codec2_fft_cfg fft_cfg; /* kiss FFT config */ | 94 | codec2_fft_cfg fft_cfg; /* kiss FFT config */ |
130 | float *Sn16k; /* Fs=16kHz input speech vector */ | 95 | float *Sn16k; /* Fs=16kHz input speech vector */ |
131 | FILE *f; | 96 | FILE *f; |
132 | } NLP; | 97 | } NLP; |
133 | 98 | ||
134 | float post_process_sub_multiples(COMP Fw[], | 99 | float post_process_sub_multiples(COMP Fw[], int pmin, int pmax, float gmax, |
135 | int pmin, int pmax, float gmax, int gmax_bin, | 100 | int gmax_bin, float *prev_f0); |
136 | float *prev_f0); | ||
137 | static void fdmdv_16_to_8(float out8k[], float in16k[], int n); | 101 | static void fdmdv_16_to_8(float out8k[], float in16k[], int n); |
138 | 102 | ||
139 | /*---------------------------------------------------------------------------*\ | 103 | /*---------------------------------------------------------------------------*\ |
@@ -144,56 +108,53 @@ static void fdmdv_16_to_8(float out8k[], float in16k[], int n); | |||
144 | 108 | ||
145 | \*---------------------------------------------------------------------------*/ | 109 | \*---------------------------------------------------------------------------*/ |
146 | 110 | ||
147 | void *nlp_create(C2CONST *c2const) | 111 | void *nlp_create(C2CONST *c2const) { |
148 | { | 112 | NLP *nlp; |
149 | NLP *nlp; | 113 | int i; |
150 | int i; | 114 | int m = c2const->m_pitch; |
151 | int m = c2const->m_pitch; | 115 | int Fs = c2const->Fs; |
152 | int Fs = c2const->Fs; | 116 | |
117 | nlp = (NLP *)malloc(sizeof(NLP)); | ||
118 | if (nlp == NULL) return NULL; | ||
153 | 119 | ||
154 | nlp = (NLP*)malloc(sizeof(NLP)); | 120 | assert((Fs == 8000) || (Fs == 16000)); |
155 | if (nlp == NULL) | 121 | nlp->Fs = Fs; |
156 | return NULL; | ||
157 | 122 | ||
158 | assert((Fs == 8000) || (Fs == 16000)); | 123 | nlp->m = m; |
159 | nlp->Fs = Fs; | ||
160 | 124 | ||
161 | nlp->m = m; | 125 | /* if running at 16kHz allocate storage for decimating filter memory */ |
162 | 126 | ||
163 | /* if running at 16kHz allocate storage for decimating filter memory */ | 127 | if (Fs == 16000) { |
128 | nlp->Sn16k = | ||
129 | (float *)malloc(sizeof(float) * (FDMDV_OS_TAPS_16K + c2const->n_samp)); | ||
130 | for (i = 0; i < FDMDV_OS_TAPS_16K; i++) { | ||
131 | nlp->Sn16k[i] = 0.0; | ||
132 | } | ||
133 | if (nlp->Sn16k == NULL) { | ||
134 | free(nlp); | ||
135 | return NULL; | ||
136 | } | ||
164 | 137 | ||
165 | if (Fs == 16000) { | 138 | /* most processing occurs at 8 kHz sample rate so halve m */ |
166 | nlp->Sn16k = (float*)malloc(sizeof(float)*(FDMDV_OS_TAPS_16K + c2const->n_samp)); | ||
167 | for(i=0; i<FDMDV_OS_TAPS_16K; i++) { | ||
168 | nlp->Sn16k[i] = 0.0; | ||
169 | } | ||
170 | if (nlp->Sn16k == NULL) { | ||
171 | free(nlp); | ||
172 | return NULL; | ||
173 | } | ||
174 | 139 | ||
175 | /* most processing occurs at 8 kHz sample rate so halve m */ | 140 | m /= 2; |
141 | } | ||
176 | 142 | ||
177 | m /= 2; | 143 | assert(m <= PMAX_M); |
178 | } | ||
179 | 144 | ||
180 | assert(m <= PMAX_M); | 145 | for (i = 0; i < m / DEC; i++) { |
181 | 146 | nlp->w[i] = 0.5 - 0.5 * cosf(2 * PI * i / (m / DEC - 1)); | |
182 | for(i=0; i<m/DEC; i++) { | 147 | } |
183 | nlp->w[i] = 0.5 - 0.5*cosf(2*PI*i/(m/DEC-1)); | ||
184 | } | ||
185 | 148 | ||
186 | for(i=0; i<PMAX_M; i++) | 149 | for (i = 0; i < PMAX_M; i++) nlp->sq[i] = 0.0; |
187 | nlp->sq[i] = 0.0; | 150 | nlp->mem_x = 0.0; |
188 | nlp->mem_x = 0.0; | 151 | nlp->mem_y = 0.0; |
189 | nlp->mem_y = 0.0; | 152 | for (i = 0; i < NLP_NTAP; i++) nlp->mem_fir[i] = 0.0; |
190 | for(i=0; i<NLP_NTAP; i++) | ||
191 | nlp->mem_fir[i] = 0.0; | ||
192 | 153 | ||
193 | nlp->fft_cfg = codec2_fft_alloc (PE_FFT_SIZE, 0, NULL, NULL); | 154 | nlp->fft_cfg = codec2_fft_alloc(PE_FFT_SIZE, 0, NULL, NULL); |
194 | assert(nlp->fft_cfg != NULL); | 155 | assert(nlp->fft_cfg != NULL); |
195 | 156 | ||
196 | return (void*)nlp; | 157 | return (void *)nlp; |
197 | } | 158 | } |
198 | 159 | ||
199 | /*---------------------------------------------------------------------------*\ | 160 | /*---------------------------------------------------------------------------*\ |
@@ -204,17 +165,16 @@ void *nlp_create(C2CONST *c2const) | |||
204 | 165 | ||
205 | \*---------------------------------------------------------------------------*/ | 166 | \*---------------------------------------------------------------------------*/ |
206 | 167 | ||
207 | void nlp_destroy(void *nlp_state) | 168 | void nlp_destroy(void *nlp_state) { |
208 | { | 169 | NLP *nlp; |
209 | NLP *nlp; | 170 | assert(nlp_state != NULL); |
210 | assert(nlp_state != NULL); | 171 | nlp = (NLP *)nlp_state; |
211 | nlp = (NLP*)nlp_state; | ||
212 | 172 | ||
213 | codec2_fft_free(nlp->fft_cfg); | 173 | codec2_fft_free(nlp->fft_cfg); |
214 | if (nlp->Fs == 16000) { | 174 | if (nlp->Fs == 16000) { |
215 | free(nlp->Sn16k); | 175 | free(nlp->Sn16k); |
216 | } | 176 | } |
217 | free(nlp_state); | 177 | free(nlp_state); |
218 | } | 178 | } |
219 | 179 | ||
220 | /*---------------------------------------------------------------------------*\ | 180 | /*---------------------------------------------------------------------------*\ |
@@ -248,162 +208,157 @@ void nlp_destroy(void *nlp_state) | |||
248 | \*---------------------------------------------------------------------------*/ | 208 | \*---------------------------------------------------------------------------*/ |
249 | 209 | ||
250 | float nlp( | 210 | float nlp( |
251 | void *nlp_state, | 211 | void *nlp_state, float Sn[], /* input speech vector */ |
252 | float Sn[], /* input speech vector */ | 212 | int n, /* frames shift (no. new samples in Sn[]) */ |
253 | int n, /* frames shift (no. new samples in Sn[]) */ | 213 | float *pitch, /* estimated pitch period in samples at current Fs */ |
254 | float *pitch, /* estimated pitch period in samples at current Fs */ | 214 | COMP Sw[], /* Freq domain version of Sn[] */ |
255 | COMP Sw[], /* Freq domain version of Sn[] */ | 215 | float W[], /* Freq domain window */ |
256 | float W[], /* Freq domain window */ | 216 | float *prev_f0 /* previous pitch f0 in Hz, memory for pitch tracking */ |
257 | float *prev_f0 /* previous pitch f0 in Hz, memory for pitch tracking */ | 217 | ) { |
258 | ) | 218 | NLP *nlp; |
259 | { | 219 | float notch; /* current notch filter output */ |
260 | NLP *nlp; | 220 | COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal (input/output) */ |
261 | float notch; /* current notch filter output */ | 221 | float gmax; |
262 | COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal (input/output) */ | 222 | int gmax_bin; |
263 | float gmax; | 223 | int m, i, j; |
264 | int gmax_bin; | 224 | float best_f0; |
265 | int m, i, j; | 225 | PROFILE_VAR(start, tnotch, filter, peakpick, window, fft, magsq, shiftmem); |
266 | float best_f0; | 226 | |
267 | PROFILE_VAR(start, tnotch, filter, peakpick, window, fft, magsq, shiftmem); | 227 | assert(nlp_state != NULL); |
268 | 228 | nlp = (NLP *)nlp_state; | |
269 | assert(nlp_state != NULL); | 229 | m = nlp->m; |
270 | nlp = (NLP*)nlp_state; | 230 | |
271 | m = nlp->m; | 231 | /* Square, notch filter at DC, and LP filter vector */ |
272 | 232 | ||
273 | /* Square, notch filter at DC, and LP filter vector */ | 233 | /* If running at 16 kHz decimate to 8 kHz, as NLP ws designed for |
274 | 234 | Fs = 8kHz. The decimating filter introduces about 3ms of delay, | |
275 | /* If running at 16 kHz decimate to 8 kHz, as NLP ws designed for | 235 | that shouldn't be a problem as pitch changes slowly. */ |
276 | Fs = 8kHz. The decimating filter introduces about 3ms of delay, | 236 | |
277 | that shouldn't be a problem as pitch changes slowly. */ | 237 | if (nlp->Fs == 8000) { |
278 | 238 | /* Square latest input samples */ | |
279 | if (nlp->Fs == 8000) { | 239 | |
280 | /* Square latest input samples */ | 240 | for (i = m - n; i < m; i++) { |
281 | 241 | nlp->sq[i] = Sn[i] * Sn[i]; | |
282 | for(i=m-n; i<m; i++) { | ||
283 | nlp->sq[i] = Sn[i]*Sn[i]; | ||
284 | } | ||
285 | } | 242 | } |
286 | else { | 243 | } else { |
287 | assert(nlp->Fs == 16000); | 244 | assert(nlp->Fs == 16000); |
288 | |||
289 | /* re-sample at 8 KHz */ | ||
290 | |||
291 | for(i=0; i<n; i++) { | ||
292 | nlp->Sn16k[FDMDV_OS_TAPS_16K+i] = Sn[m-n+i]; | ||
293 | } | ||
294 | |||
295 | m /= 2; n /= 2; | ||
296 | 245 | ||
297 | float Sn8k[n]; | 246 | /* re-sample at 8 KHz */ |
298 | fdmdv_16_to_8(Sn8k, &nlp->Sn16k[FDMDV_OS_TAPS_16K], n); | ||
299 | 247 | ||
300 | /* Square latest input samples */ | 248 | for (i = 0; i < n; i++) { |
301 | 249 | nlp->Sn16k[FDMDV_OS_TAPS_16K + i] = Sn[m - n + i]; | |
302 | for(i=m-n, j=0; i<m; i++, j++) { | ||
303 | nlp->sq[i] = Sn8k[j]*Sn8k[j]; | ||
304 | } | ||
305 | assert(j <= n); | ||
306 | } | ||
307 | //fprintf(stderr, "n: %d m: %d\n", n, m); | ||
308 | |||
309 | PROFILE_SAMPLE(start); | ||
310 | |||
311 | for(i=m-n; i<m; i++) { /* notch filter at DC */ | ||
312 | notch = nlp->sq[i] - nlp->mem_x; | ||
313 | notch += COEFF*nlp->mem_y; | ||
314 | nlp->mem_x = nlp->sq[i]; | ||
315 | nlp->mem_y = notch; | ||
316 | nlp->sq[i] = notch + 1.0; /* With 0 input vectors to codec, | ||
317 | kiss_fft() would take a long | ||
318 | time to execute when running in | ||
319 | real time. Problem was traced | ||
320 | to kiss_fft function call in | ||
321 | this function. Adding this small | ||
322 | constant fixed problem. Not | ||
323 | exactly sure why. */ | ||
324 | } | 250 | } |
325 | 251 | ||
326 | PROFILE_SAMPLE_AND_LOG(tnotch, start, " square and notch"); | 252 | m /= 2; |
253 | n /= 2; | ||
327 | 254 | ||
328 | for(i=m-n; i<m; i++) { /* FIR filter vector */ | 255 | float Sn8k[n]; |
256 | fdmdv_16_to_8(Sn8k, &nlp->Sn16k[FDMDV_OS_TAPS_16K], n); | ||
329 | 257 | ||
330 | for(j=0; j<NLP_NTAP-1; j++) | 258 | /* Square latest input samples */ |
331 | nlp->mem_fir[j] = nlp->mem_fir[j+1]; | ||
332 | nlp->mem_fir[NLP_NTAP-1] = nlp->sq[i]; | ||
333 | 259 | ||
334 | nlp->sq[i] = 0.0; | 260 | for (i = m - n, j = 0; i < m; i++, j++) { |
335 | for(j=0; j<NLP_NTAP; j++) | 261 | nlp->sq[i] = Sn8k[j] * Sn8k[j]; |
336 | nlp->sq[i] += nlp->mem_fir[j]*nlp_fir[j]; | ||
337 | } | 262 | } |
338 | 263 | assert(j <= n); | |
339 | PROFILE_SAMPLE_AND_LOG(filter, tnotch, " filter"); | 264 | } |
340 | 265 | // fprintf(stderr, "n: %d m: %d\n", n, m); | |
341 | /* Decimate and DFT */ | 266 | |
342 | 267 | PROFILE_SAMPLE(start); | |
343 | for(i=0; i<PE_FFT_SIZE; i++) { | 268 | |
344 | Fw[i].real = 0.0; | 269 | for (i = m - n; i < m; i++) { /* notch filter at DC */ |
345 | Fw[i].imag = 0.0; | 270 | notch = nlp->sq[i] - nlp->mem_x; |
346 | } | 271 | notch += COEFF * nlp->mem_y; |
347 | for(i=0; i<m/DEC; i++) { | 272 | nlp->mem_x = nlp->sq[i]; |
348 | Fw[i].real = nlp->sq[i*DEC]*nlp->w[i]; | 273 | nlp->mem_y = notch; |
349 | } | 274 | nlp->sq[i] = notch + 1.0; /* With 0 input vectors to codec, |
350 | PROFILE_SAMPLE_AND_LOG(window, filter, " window"); | 275 | kiss_fft() would take a long |
351 | #ifdef DUMP | 276 | time to execute when running in |
352 | dump_dec(Fw); | 277 | real time. Problem was traced |
353 | #endif | 278 | to kiss_fft function call in |
354 | 279 | this function. Adding this small | |
355 | // FIXME: check if this can be converted to a real fft | 280 | constant fixed problem. Not |
356 | // since all imag inputs are 0 | 281 | exactly sure why. */ |
357 | codec2_fft_inplace(nlp->fft_cfg, Fw); | 282 | } |
358 | PROFILE_SAMPLE_AND_LOG(fft, window, " fft"); | 283 | |
359 | 284 | PROFILE_SAMPLE_AND_LOG(tnotch, start, " square and notch"); | |
360 | for(i=0; i<PE_FFT_SIZE; i++) | 285 | |
361 | Fw[i].real = Fw[i].real*Fw[i].real + Fw[i].imag*Fw[i].imag; | 286 | for (i = m - n; i < m; i++) { /* FIR filter vector */ |
362 | 287 | ||
363 | PROFILE_SAMPLE_AND_LOG(magsq, fft, " mag sq"); | 288 | for (j = 0; j < NLP_NTAP - 1; j++) nlp->mem_fir[j] = nlp->mem_fir[j + 1]; |
364 | #ifdef DUMP | 289 | nlp->mem_fir[NLP_NTAP - 1] = nlp->sq[i]; |
365 | dump_sq(m, nlp->sq); | 290 | |
366 | dump_Fw(Fw); | 291 | nlp->sq[i] = 0.0; |
367 | #endif | 292 | for (j = 0; j < NLP_NTAP; j++) nlp->sq[i] += nlp->mem_fir[j] * nlp_fir[j]; |
368 | 293 | } | |
369 | /* todo: express everything in f0, as pitch in samples is dep on Fs */ | 294 | |
370 | 295 | PROFILE_SAMPLE_AND_LOG(filter, tnotch, " filter"); | |
371 | int pmin = floor(SAMPLE_RATE*P_MIN_S); | 296 | |
372 | int pmax = floor(SAMPLE_RATE*P_MAX_S); | 297 | /* Decimate and DFT */ |
373 | 298 | ||
374 | /* find global peak */ | 299 | for (i = 0; i < PE_FFT_SIZE; i++) { |
375 | 300 | Fw[i].real = 0.0; | |
376 | gmax = 0.0; | 301 | Fw[i].imag = 0.0; |
377 | gmax_bin = PE_FFT_SIZE*DEC/pmax; | 302 | } |
378 | for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) { | 303 | for (i = 0; i < m / DEC; i++) { |
379 | if (Fw[i].real > gmax) { | 304 | Fw[i].real = nlp->sq[i * DEC] * nlp->w[i]; |
380 | gmax = Fw[i].real; | 305 | } |
381 | gmax_bin = i; | 306 | PROFILE_SAMPLE_AND_LOG(window, filter, " window"); |
382 | } | 307 | #ifdef DUMP |
308 | dump_dec(Fw); | ||
309 | #endif | ||
310 | |||
311 | // FIXME: check if this can be converted to a real fft | ||
312 | // since all imag inputs are 0 | ||
313 | codec2_fft_inplace(nlp->fft_cfg, Fw); | ||
314 | PROFILE_SAMPLE_AND_LOG(fft, window, " fft"); | ||
315 | |||
316 | for (i = 0; i < PE_FFT_SIZE; i++) | ||
317 | Fw[i].real = Fw[i].real * Fw[i].real + Fw[i].imag * Fw[i].imag; | ||
318 | |||
319 | PROFILE_SAMPLE_AND_LOG(magsq, fft, " mag sq"); | ||
320 | #ifdef DUMP | ||
321 | dump_sq(m, nlp->sq); | ||
322 | dump_Fw(Fw); | ||
323 | #endif | ||
324 | |||
325 | /* todo: express everything in f0, as pitch in samples is dep on Fs */ | ||
326 | |||
327 | int pmin = floor(SAMPLE_RATE * P_MIN_S); | ||
328 | int pmax = floor(SAMPLE_RATE * P_MAX_S); | ||
329 | |||
330 | /* find global peak */ | ||
331 | |||
332 | gmax = 0.0; | ||
333 | gmax_bin = PE_FFT_SIZE * DEC / pmax; | ||
334 | for (i = PE_FFT_SIZE * DEC / pmax; i <= PE_FFT_SIZE * DEC / pmin; i++) { | ||
335 | if (Fw[i].real > gmax) { | ||
336 | gmax = Fw[i].real; | ||
337 | gmax_bin = i; | ||
383 | } | 338 | } |
339 | } | ||
384 | 340 | ||
385 | PROFILE_SAMPLE_AND_LOG(peakpick, magsq, " peak pick"); | 341 | PROFILE_SAMPLE_AND_LOG(peakpick, magsq, " peak pick"); |
386 | 342 | ||
387 | best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_f0); | 343 | best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_f0); |
388 | 344 | ||
389 | PROFILE_SAMPLE_AND_LOG(shiftmem, peakpick, " post process"); | 345 | PROFILE_SAMPLE_AND_LOG(shiftmem, peakpick, " post process"); |
390 | 346 | ||
391 | /* Shift samples in buffer to make room for new samples */ | 347 | /* Shift samples in buffer to make room for new samples */ |
392 | 348 | ||
393 | for(i=0; i<m-n; i++) | 349 | for (i = 0; i < m - n; i++) nlp->sq[i] = nlp->sq[i + n]; |
394 | nlp->sq[i] = nlp->sq[i+n]; | ||
395 | 350 | ||
396 | /* return pitch period in samples and F0 estimate */ | 351 | /* return pitch period in samples and F0 estimate */ |
397 | 352 | ||
398 | *pitch = (float)nlp->Fs/best_f0; | 353 | *pitch = (float)nlp->Fs / best_f0; |
399 | 354 | ||
400 | PROFILE_SAMPLE_AND_LOG2(shiftmem, " shift mem"); | 355 | PROFILE_SAMPLE_AND_LOG2(shiftmem, " shift mem"); |
401 | 356 | ||
402 | PROFILE_SAMPLE_AND_LOG2(start, " nlp int"); | 357 | PROFILE_SAMPLE_AND_LOG2(start, " nlp int"); |
403 | 358 | ||
404 | *prev_f0 = best_f0; | 359 | *prev_f0 = best_f0; |
405 | 360 | ||
406 | return(best_f0); | 361 | return (best_f0); |
407 | } | 362 | } |
408 | 363 | ||
409 | /*---------------------------------------------------------------------------*\ | 364 | /*---------------------------------------------------------------------------*\ |
@@ -427,59 +382,55 @@ float nlp( | |||
427 | 382 | ||
428 | \*---------------------------------------------------------------------------*/ | 383 | \*---------------------------------------------------------------------------*/ |
429 | 384 | ||
430 | float post_process_sub_multiples(COMP Fw[], | 385 | float post_process_sub_multiples(COMP Fw[], int pmin, int pmax, float gmax, |
431 | int pmin, int pmax, float gmax, int gmax_bin, | 386 | int gmax_bin, float *prev_f0) { |
432 | float *prev_f0) | 387 | int min_bin, cmax_bin; |
433 | { | 388 | int mult; |
434 | int min_bin, cmax_bin; | 389 | float thresh, best_f0; |
435 | int mult; | 390 | int b, bmin, bmax, lmax_bin; |
436 | float thresh, best_f0; | 391 | float lmax; |
437 | int b, bmin, bmax, lmax_bin; | 392 | int prev_f0_bin; |
438 | float lmax; | 393 | |
439 | int prev_f0_bin; | 394 | /* post process estimate by searching submultiples */ |
440 | 395 | ||
441 | /* post process estimate by searching submultiples */ | 396 | mult = 2; |
442 | 397 | min_bin = PE_FFT_SIZE * DEC / pmax; | |
443 | mult = 2; | 398 | cmax_bin = gmax_bin; |
444 | min_bin = PE_FFT_SIZE*DEC/pmax; | 399 | prev_f0_bin = *prev_f0 * (PE_FFT_SIZE * DEC) / SAMPLE_RATE; |
445 | cmax_bin = gmax_bin; | 400 | |
446 | prev_f0_bin = *prev_f0*(PE_FFT_SIZE*DEC)/SAMPLE_RATE; | 401 | while (gmax_bin / mult >= min_bin) { |
447 | 402 | b = gmax_bin / mult; /* determine search interval */ | |
448 | while(gmax_bin/mult >= min_bin) { | 403 | bmin = 0.8 * b; |
449 | 404 | bmax = 1.2 * b; | |
450 | b = gmax_bin/mult; /* determine search interval */ | 405 | if (bmin < min_bin) bmin = min_bin; |
451 | bmin = 0.8*b; | 406 | |
452 | bmax = 1.2*b; | 407 | /* lower threshold to favour previous frames pitch estimate, |
453 | if (bmin < min_bin) | 408 | this is a form of pitch tracking */ |
454 | bmin = min_bin; | 409 | |
455 | 410 | if ((prev_f0_bin > bmin) && (prev_f0_bin < bmax)) | |
456 | /* lower threshold to favour previous frames pitch estimate, | 411 | thresh = CNLP * 0.5 * gmax; |
457 | this is a form of pitch tracking */ | 412 | else |
458 | 413 | thresh = CNLP * gmax; | |
459 | if ((prev_f0_bin > bmin) && (prev_f0_bin < bmax)) | 414 | |
460 | thresh = CNLP*0.5*gmax; | 415 | lmax = 0; |
461 | else | 416 | lmax_bin = bmin; |
462 | thresh = CNLP*gmax; | 417 | for (b = bmin; b <= bmax; b++) /* look for maximum in interval */ |
463 | 418 | if (Fw[b].real > lmax) { | |
464 | lmax = 0; | 419 | lmax = Fw[b].real; |
465 | lmax_bin = bmin; | 420 | lmax_bin = b; |
466 | for (b=bmin; b<=bmax; b++) /* look for maximum in interval */ | 421 | } |
467 | if (Fw[b].real > lmax) { | 422 | |
468 | lmax = Fw[b].real; | 423 | if (lmax > thresh) |
469 | lmax_bin = b; | 424 | if ((lmax > Fw[lmax_bin - 1].real) && (lmax > Fw[lmax_bin + 1].real)) { |
470 | } | 425 | cmax_bin = lmax_bin; |
471 | 426 | } | |
472 | if (lmax > thresh) | 427 | |
473 | if ((lmax > Fw[lmax_bin-1].real) && (lmax > Fw[lmax_bin+1].real)) { | 428 | mult++; |
474 | cmax_bin = lmax_bin; | 429 | } |
475 | } | 430 | |
476 | 431 | best_f0 = (float)cmax_bin * SAMPLE_RATE / (PE_FFT_SIZE * DEC); | |
477 | mult++; | 432 | |
478 | } | 433 | return best_f0; |
479 | |||
480 | best_f0 = (float)cmax_bin*SAMPLE_RATE/(PE_FFT_SIZE*DEC); | ||
481 | |||
482 | return best_f0; | ||
483 | } | 434 | } |
484 | 435 | ||
485 | /*---------------------------------------------------------------------------*\ | 436 | /*---------------------------------------------------------------------------*\ |
@@ -502,20 +453,18 @@ float post_process_sub_multiples(COMP Fw[], | |||
502 | 453 | ||
503 | \*---------------------------------------------------------------------------*/ | 454 | \*---------------------------------------------------------------------------*/ |
504 | 455 | ||
505 | static void fdmdv_16_to_8(float out8k[], float in16k[], int n) | 456 | static void fdmdv_16_to_8(float out8k[], float in16k[], int n) { |
506 | { | 457 | float acc; |
507 | float acc; | 458 | int i, j, k; |
508 | int i,j,k; | ||
509 | 459 | ||
510 | for(i=0, k=0; k<n; i+=FDMDV_OS, k++) { | 460 | for (i = 0, k = 0; k < n; i += FDMDV_OS, k++) { |
511 | acc = 0.0; | 461 | acc = 0.0; |
512 | for(j=0; j<FDMDV_OS_TAPS_16K; j++) | 462 | for (j = 0; j < FDMDV_OS_TAPS_16K; j++) |
513 | acc += fdmdv_os_filter[j]*in16k[i-j]; | 463 | acc += fdmdv_os_filter[j] * in16k[i - j]; |
514 | out8k[k] = acc; | 464 | out8k[k] = acc; |
515 | } | 465 | } |
516 | 466 | ||
517 | /* update filter memory */ | 467 | /* update filter memory */ |
518 | 468 | ||
519 | for(i=-FDMDV_OS_TAPS_16K; i<0; i++) | 469 | for (i = -FDMDV_OS_TAPS_16K; i < 0; i++) in16k[i] = in16k[i + n * FDMDV_OS]; |
520 | in16k[i] = in16k[i + n*FDMDV_OS]; | ||
521 | } | 470 | } |
@@ -29,10 +29,11 @@ | |||
29 | #define __NLP__ | 29 | #define __NLP__ |
30 | 30 | ||
31 | #include "comp.h" | 31 | #include "comp.h" |
32 | #include "defines.h" | ||
32 | 33 | ||
33 | void *nlp_create(C2CONST *c2const); | 34 | void *nlp_create(C2CONST *c2const); |
34 | void nlp_destroy(void *nlp_state); | 35 | void nlp_destroy(void *nlp_state); |
35 | float nlp(void *nlp_state, float Sn[], int n, | 36 | float nlp(void *nlp_state, float Sn[], int n, float *pitch_samples, COMP Sw[], |
36 | float *pitch_samples, COMP Sw[], float W[], float *prev_f0); | 37 | float W[], float *prev_f0); |
37 | 38 | ||
38 | #endif | 39 | #endif |
@@ -1,53 +1,35 @@ | |||
1 | /* Generate using fir1(47,1/2) in Octave */ | 1 | /* Generate using fir1(47,1/2) in Octave */ |
2 | 2 | ||
3 | static const float fdmdv_os_filter[]= { | 3 | static const float fdmdv_os_filter[] = { |
4 | -0.0008215855034550382, | 4 | -0.0008215855034550382, -0.0007833023901802921, 0.001075563790768233, |
5 | -0.0007833023901802921, | 5 | 0.001199092367787555, -0.001765309502928316, -0.002055372115328064, |
6 | 0.001075563790768233, | 6 | 0.002986877604154257, 0.003462567920638414, -0.004856570111126334, |
7 | 0.001199092367787555, | 7 | -0.005563143845031497, 0.007533613299748122, 0.008563932468880897, |
8 | -0.001765309502928316, | 8 | -0.01126857129039911, -0.01280782411693687, 0.01651443896361847, |
9 | -0.002055372115328064, | 9 | 0.01894875110322284, -0.02421604439474981, -0.02845107338464062, |
10 | 0.002986877604154257, | 10 | 0.03672973563400258, 0.04542046150312214, -0.06189165826716491, |
11 | 0.003462567920638414, | 11 | -0.08721876380763803, 0.1496157094199961, 0.4497962274137046, |
12 | -0.004856570111126334, | 12 | 0.4497962274137046, 0.1496157094199961, -0.08721876380763803, |
13 | -0.005563143845031497, | 13 | -0.0618916582671649, 0.04542046150312216, 0.03672973563400257, |
14 | 0.007533613299748122, | 14 | -0.02845107338464062, -0.02421604439474984, 0.01894875110322284, |
15 | 0.008563932468880897, | 15 | 0.01651443896361848, -0.01280782411693687, -0.0112685712903991, |
16 | -0.01126857129039911, | 16 | 0.008563932468880899, 0.007533613299748123, -0.005563143845031501, |
17 | -0.01280782411693687, | 17 | -0.004856570111126346, 0.003462567920638419, 0.002986877604154259, |
18 | 0.01651443896361847, | 18 | -0.002055372115328063, -0.001765309502928318, 0.001199092367787557, |
19 | 0.01894875110322284, | 19 | 0.001075563790768233, -0.0007833023901802925, -0.0008215855034550383}; |
20 | -0.02421604439474981, | ||
21 | -0.02845107338464062, | ||
22 | 0.03672973563400258, | ||
23 | 0.04542046150312214, | ||
24 | -0.06189165826716491, | ||
25 | -0.08721876380763803, | ||
26 | 0.1496157094199961, | ||
27 | 0.4497962274137046, | ||
28 | 0.4497962274137046, | ||
29 | 0.1496157094199961, | ||
30 | -0.08721876380763803, | ||
31 | -0.0618916582671649, | ||
32 | 0.04542046150312216, | ||
33 | 0.03672973563400257, | ||
34 | -0.02845107338464062, | ||
35 | -0.02421604439474984, | ||
36 | 0.01894875110322284, | ||
37 | 0.01651443896361848, | ||
38 | -0.01280782411693687, | ||
39 | -0.0112685712903991, | ||
40 | 0.008563932468880899, | ||
41 | 0.007533613299748123, | ||
42 | -0.005563143845031501, | ||
43 | -0.004856570111126346, | ||
44 | 0.003462567920638419, | ||
45 | 0.002986877604154259, | ||
46 | -0.002055372115328063, | ||
47 | -0.001765309502928318, | ||
48 | 0.001199092367787557, | ||
49 | 0.001075563790768233, | ||
50 | -0.0007833023901802925, | ||
51 | -0.0008215855034550383 | ||
52 | }; | ||
53 | 20 | ||
21 | /* Generate using fir1(47,1/6) in Octave */ | ||
22 | |||
23 | static const float fdmdv_os_filter48[] = { | ||
24 | -3.55606818e-04, -8.98615286e-04, -1.40119781e-03, -1.71713852e-03, | ||
25 | -1.56471179e-03, -6.28128960e-04, 1.24522223e-03, 3.83138676e-03, | ||
26 | 6.41309478e-03, 7.85893186e-03, 6.93514929e-03, 2.79361991e-03, | ||
27 | -4.51051400e-03, -1.36671853e-02, -2.21034939e-02, -2.64084653e-02, | ||
28 | -2.31425052e-02, -9.84218694e-03, 1.40648474e-02, 4.67316298e-02, | ||
29 | 8.39615986e-02, 1.19925275e-01, 1.48381174e-01, 1.64097819e-01, | ||
30 | 1.64097819e-01, 1.48381174e-01, 1.19925275e-01, 8.39615986e-02, | ||
31 | 4.67316298e-02, 1.40648474e-02, -9.84218694e-03, -2.31425052e-02, | ||
32 | -2.64084653e-02, -2.21034939e-02, -1.36671853e-02, -4.51051400e-03, | ||
33 | 2.79361991e-03, 6.93514929e-03, 7.85893186e-03, 6.41309478e-03, | ||
34 | 3.83138676e-03, 1.24522223e-03, -6.28128960e-04, -1.56471179e-03, | ||
35 | -1.71713852e-03, -1.40119781e-03, -8.98615286e-04, -3.55606818e-04}; | ||
@@ -15,19 +15,20 @@ | |||
15 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 15 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <stdio.h> | ||
19 | |||
18 | #include "defines.h" | 20 | #include "defines.h" |
19 | #include "quantise.h" | 21 | #include "quantise.h" |
20 | #include <stdio.h> | ||
21 | 22 | ||
22 | /* Compile-time constants */ | 23 | /* Compile-time constants */ |
23 | /* Size of unsigned char in bits. Assumes 8 bits-per-char. */ | 24 | /* Size of unsigned char in bits. Assumes 8 bits-per-char. */ |
24 | static const unsigned int WordSize = 8; | 25 | static const unsigned int WordSize = 8; |
25 | 26 | ||
26 | /* Mask to pick the bit component out of bitIndex. */ | 27 | /* Mask to pick the bit component out of bitIndex. */ |
27 | static const unsigned int IndexMask = 0x7; | 28 | static const unsigned int IndexMask = 0x7; |
28 | 29 | ||
29 | /* Used to pick the word component out of bitIndex. */ | 30 | /* Used to pick the word component out of bitIndex. */ |
30 | static const unsigned int ShiftRight = 3; | 31 | static const unsigned int ShiftRight = 3; |
31 | 32 | ||
32 | /** Pack a bit field into a bit string, encoding the field in Gray code. | 33 | /** Pack a bit field into a bit string, encoding the field in Gray code. |
33 | * | 34 | * |
@@ -44,86 +45,76 @@ static const unsigned int ShiftRight = 3; | |||
44 | * compatibility with the rest of the code, indices are always expected to | 45 | * compatibility with the rest of the code, indices are always expected to |
45 | * be >= 0. | 46 | * be >= 0. |
46 | */ | 47 | */ |
47 | void | 48 | void pack(unsigned char* bitArray, /* The output bit string. */ |
48 | pack( | 49 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
49 | unsigned char * bitArray, /* The output bit string. */ | 50 | int field, /* The bit field to be packed. */ |
50 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 51 | unsigned int fieldWidth /* Width of the field in BITS, not bytes. */ |
51 | int field, /* The bit field to be packed. */ | 52 | ) { |
52 | unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ | 53 | pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1); |
53 | ) | ||
54 | { | ||
55 | pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1); | ||
56 | } | 54 | } |
57 | 55 | ||
58 | void | 56 | void pack_natural_or_gray( |
59 | pack_natural_or_gray( | 57 | unsigned char* bitArray, /* The output bit string. */ |
60 | unsigned char * bitArray, /* The output bit string. */ | 58 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
61 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 59 | int field, /* The bit field to be packed. */ |
62 | int field, /* The bit field to be packed. */ | 60 | unsigned int fieldWidth, /* Width of the field in BITS, not bytes. */ |
63 | unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */ | 61 | unsigned int gray /* non-zero for gray coding */ |
64 | unsigned int gray /* non-zero for gray coding */ | 62 | ) { |
65 | ) | ||
66 | { | ||
67 | if (gray) { | 63 | if (gray) { |
68 | /* Convert the field to Gray code */ | 64 | /* Convert the field to Gray code */ |
69 | field = (field >> 1) ^ field; | 65 | field = (field >> 1) ^ field; |
70 | } | 66 | } |
71 | 67 | ||
72 | do { | 68 | do { |
73 | unsigned int bI = *bitIndex; | 69 | unsigned int bI = *bitIndex; |
74 | unsigned int bitsLeft = WordSize - (bI & IndexMask); | 70 | unsigned int bitsLeft = WordSize - (bI & IndexMask); |
75 | unsigned int sliceWidth = | 71 | unsigned int sliceWidth = bitsLeft < fieldWidth ? bitsLeft : fieldWidth; |
76 | bitsLeft < fieldWidth ? bitsLeft : fieldWidth; | 72 | unsigned int wordIndex = bI >> ShiftRight; |
77 | unsigned int wordIndex = bI >> ShiftRight; | ||
78 | 73 | ||
79 | bitArray[wordIndex] |= | 74 | bitArray[wordIndex] |= ((unsigned char)((field >> (fieldWidth - sliceWidth)) |
80 | ((unsigned char)((field >> (fieldWidth - sliceWidth)) | 75 | << (bitsLeft - sliceWidth))); |
81 | << (bitsLeft - sliceWidth))); | ||
82 | 76 | ||
83 | *bitIndex = bI + sliceWidth; | 77 | *bitIndex = bI + sliceWidth; |
84 | fieldWidth -= sliceWidth; | 78 | fieldWidth -= sliceWidth; |
85 | } while ( fieldWidth != 0 ); | 79 | } while (fieldWidth != 0); |
86 | } | 80 | } |
87 | 81 | ||
88 | /** Unpack a field from a bit string, converting from Gray code to binary. | 82 | /** Unpack a field from a bit string, converting from Gray code to binary. |
89 | * | 83 | * |
90 | */ | 84 | */ |
91 | int | 85 | int unpack( |
92 | unpack( | 86 | const unsigned char* bitArray, /* The input bit string. */ |
93 | const unsigned char * bitArray, /* The input bit string. */ | 87 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
94 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 88 | unsigned int fieldWidth /* Width of the field in BITS, not bytes. */ |
95 | unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ | 89 | ) { |
96 | ) | 90 | return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1); |
97 | { | ||
98 | return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1); | ||
99 | } | 91 | } |
100 | 92 | ||
101 | /** Unpack a field from a bit string, to binary, optionally using | 93 | /** Unpack a field from a bit string, to binary, optionally using |
102 | * natural or Gray code. | 94 | * natural or Gray code. |
103 | * | 95 | * |
104 | */ | 96 | */ |
105 | int | 97 | int unpack_natural_or_gray( |
106 | unpack_natural_or_gray( | 98 | const unsigned char* bitArray, /* The input bit string. */ |
107 | const unsigned char * bitArray, /* The input bit string. */ | 99 | unsigned int* bitIndex, /* Index into the string in BITS, not bytes.*/ |
108 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ | 100 | unsigned int fieldWidth, /* Width of the field in BITS, not bytes. */ |
109 | unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */ | 101 | unsigned int gray /* non-zero for Gray coding */ |
110 | unsigned int gray /* non-zero for Gray coding */ | 102 | ) { |
111 | ) | 103 | unsigned int field = 0; |
112 | { | 104 | unsigned int t; |
113 | unsigned int field = 0; | ||
114 | unsigned int t; | ||
115 | 105 | ||
116 | do { | 106 | do { |
117 | unsigned int bI = *bitIndex; | 107 | unsigned int bI = *bitIndex; |
118 | unsigned int bitsLeft = WordSize - (bI & IndexMask); | 108 | unsigned int bitsLeft = WordSize - (bI & IndexMask); |
119 | unsigned int sliceWidth = | 109 | unsigned int sliceWidth = bitsLeft < fieldWidth ? bitsLeft : fieldWidth; |
120 | bitsLeft < fieldWidth ? bitsLeft : fieldWidth; | ||
121 | 110 | ||
122 | field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth)); | 111 | field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & |
112 | ((1 << sliceWidth) - 1)) | ||
113 | << (fieldWidth - sliceWidth)); | ||
123 | 114 | ||
124 | *bitIndex = bI + sliceWidth; | 115 | *bitIndex = bI + sliceWidth; |
125 | fieldWidth -= sliceWidth; | 116 | fieldWidth -= sliceWidth; |
126 | } while ( fieldWidth != 0 ); | 117 | } while (fieldWidth != 0); |
127 | 118 | ||
128 | if (gray) { | 119 | if (gray) { |
129 | /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ | 120 | /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ |
@@ -131,8 +122,7 @@ unpack_natural_or_gray( | |||
131 | t ^= (t >> 4); | 122 | t ^= (t >> 4); |
132 | t ^= (t >> 2); | 123 | t ^= (t >> 2); |
133 | t ^= (t >> 1); | 124 | t ^= (t >> 1); |
134 | } | 125 | } else { |
135 | else { | ||
136 | t = field; | 126 | t = field; |
137 | } | 127 | } |
138 | 128 | ||
@@ -25,18 +25,19 @@ | |||
25 | along with this program; if not,see <http://www.gnu.org/licenses/>. | 25 | along with this program; if not,see <http://www.gnu.org/licenses/>. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "defines.h" | ||
29 | #include "phase.h" | 28 | #include "phase.h" |
30 | #include "kiss_fft.h" | ||
31 | #include "comp.h" | ||
32 | #include "comp_prim.h" | ||
33 | #include "sine.h" | ||
34 | 29 | ||
35 | #include <assert.h> | 30 | #include <assert.h> |
36 | #include <ctype.h> | 31 | #include <ctype.h> |
37 | #include <math.h> | 32 | #include <math.h> |
38 | #include <string.h> | ||
39 | #include <stdlib.h> | 33 | #include <stdlib.h> |
34 | #include <string.h> | ||
35 | |||
36 | #include "comp.h" | ||
37 | #include "comp_prim.h" | ||
38 | #include "defines.h" | ||
39 | #include "kiss_fft.h" | ||
40 | #include "sine.h" | ||
40 | 41 | ||
41 | /*---------------------------------------------------------------------------*\ | 42 | /*---------------------------------------------------------------------------*\ |
42 | 43 | ||
@@ -47,25 +48,23 @@ | |||
47 | 48 | ||
48 | \*---------------------------------------------------------------------------*/ | 49 | \*---------------------------------------------------------------------------*/ |
49 | 50 | ||
50 | void sample_phase(MODEL *model, | 51 | void sample_phase(MODEL *model, COMP H[], |
51 | COMP H[], | 52 | COMP A[] /* LPC analysis filter in freq domain */ |
52 | COMP A[] /* LPC analysis filter in freq domain */ | 53 | ) { |
53 | ) | 54 | int m, b; |
54 | { | 55 | float r; |
55 | int m, b; | ||
56 | float r; | ||
57 | 56 | ||
58 | r = TWO_PI/(FFT_ENC); | 57 | r = TWO_PI / (FFT_ENC); |
59 | 58 | ||
60 | /* Sample phase at harmonics */ | 59 | /* Sample phase at harmonics */ |
61 | 60 | ||
62 | for(m=1; m<=model->L; m++) { | 61 | for (m = 1; m <= model->L; m++) { |
63 | b = (int)(m*model->Wo/r + 0.5); | 62 | b = (int)(m * model->Wo / r + 0.5); |
64 | H[m] = cconj(A[b]); /* synth filter 1/A is opposite phase to analysis filter */ | 63 | H[m] = |
65 | } | 64 | cconj(A[b]); /* synth filter 1/A is opposite phase to analysis filter */ |
65 | } | ||
66 | } | 66 | } |
67 | 67 | ||
68 | |||
69 | /*---------------------------------------------------------------------------*\ | 68 | /*---------------------------------------------------------------------------*\ |
70 | 69 | ||
71 | phase_synth_zero_order() | 70 | phase_synth_zero_order() |
@@ -158,64 +157,56 @@ void sample_phase(MODEL *model, | |||
158 | \*---------------------------------------------------------------------------*/ | 157 | \*---------------------------------------------------------------------------*/ |
159 | 158 | ||
160 | void phase_synth_zero_order( | 159 | void phase_synth_zero_order( |
161 | int n_samp, | 160 | int n_samp, MODEL *model, |
162 | MODEL *model, | 161 | float *ex_phase, /* excitation phase of fundamental */ |
163 | float *ex_phase, /* excitation phase of fundamental */ | 162 | COMP H[] /* L synthesis filter freq domain samples */ |
164 | COMP H[] /* L synthesis filter freq domain samples */ | 163 | |
165 | 164 | ) { | |
166 | ) | 165 | int m; |
167 | { | 166 | float new_phi; |
168 | int m; | 167 | COMP Ex[MAX_AMP + 1]; /* excitation samples */ |
169 | float new_phi; | 168 | COMP A_[MAX_AMP + 1]; /* synthesised harmonic samples */ |
170 | COMP Ex[MAX_AMP+1]; /* excitation samples */ | 169 | |
171 | COMP A_[MAX_AMP+1]; /* synthesised harmonic samples */ | 170 | /* |
172 | 171 | Update excitation fundamental phase track, this sets the position | |
173 | /* | 172 | of each pitch pulse during voiced speech. After much experiment |
174 | Update excitation fundamental phase track, this sets the position | 173 | I found that using just this frame's Wo improved quality for UV |
175 | of each pitch pulse during voiced speech. After much experiment | 174 | sounds compared to interpolating two frames Wo like this: |
176 | I found that using just this frame's Wo improved quality for UV | 175 | |
177 | sounds compared to interpolating two frames Wo like this: | 176 | ex_phase[0] += (*prev_Wo+model->Wo)*N_SAMP/2; |
178 | 177 | */ | |
179 | ex_phase[0] += (*prev_Wo+model->Wo)*N_SAMP/2; | 178 | |
180 | */ | 179 | ex_phase[0] += (model->Wo) * n_samp; |
181 | 180 | ex_phase[0] -= TWO_PI * floorf(ex_phase[0] / TWO_PI + 0.5); | |
182 | ex_phase[0] += (model->Wo)*n_samp; | 181 | |
183 | ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5); | 182 | for (m = 1; m <= model->L; m++) { |
184 | 183 | /* generate excitation */ | |
185 | for(m=1; m<=model->L; m++) { | 184 | |
186 | 185 | if (model->voiced) { | |
187 | /* generate excitation */ | 186 | Ex[m].real = cosf(ex_phase[0] * m); |
188 | 187 | Ex[m].imag = sinf(ex_phase[0] * m); | |
189 | if (model->voiced) { | 188 | } else { |
190 | 189 | /* When a few samples were tested I found that LPC filter | |
191 | Ex[m].real = cosf(ex_phase[0]*m); | 190 | phase is not needed in the unvoiced case, but no harm in |
192 | Ex[m].imag = sinf(ex_phase[0]*m); | 191 | keeping it. |
193 | } | 192 | */ |
194 | else { | 193 | float phi = TWO_PI * (float)codec2_rand() / CODEC2_RAND_MAX; |
195 | 194 | Ex[m].real = cosf(phi); | |
196 | /* When a few samples were tested I found that LPC filter | 195 | Ex[m].imag = sinf(phi); |
197 | phase is not needed in the unvoiced case, but no harm in | 196 | } |
198 | keeping it. | ||
199 | */ | ||
200 | float phi = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX; | ||
201 | Ex[m].real = cosf(phi); | ||
202 | Ex[m].imag = sinf(phi); | ||
203 | } | ||
204 | |||
205 | /* filter using LPC filter */ | ||
206 | 197 | ||
207 | A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag; | 198 | /* filter using LPC filter */ |
208 | A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag; | ||
209 | 199 | ||
210 | /* modify sinusoidal phase */ | 200 | A_[m].real = H[m].real * Ex[m].real - H[m].imag * Ex[m].imag; |
201 | A_[m].imag = H[m].imag * Ex[m].real + H[m].real * Ex[m].imag; | ||
211 | 202 | ||
212 | new_phi = atan2f(A_[m].imag, A_[m].real+1E-12); | 203 | /* modify sinusoidal phase */ |
213 | model->phi[m] = new_phi; | ||
214 | } | ||
215 | 204 | ||
205 | new_phi = atan2f(A_[m].imag, A_[m].real + 1E-12); | ||
206 | model->phi[m] = new_phi; | ||
207 | } | ||
216 | } | 208 | } |
217 | 209 | ||
218 | |||
219 | /*---------------------------------------------------------------------------*\ | 210 | /*---------------------------------------------------------------------------*\ |
220 | 211 | ||
221 | FUNCTION....: mag_to_phase | 212 | FUNCTION....: mag_to_phase |
@@ -230,60 +221,55 @@ void phase_synth_zero_order( | |||
230 | 221 | ||
231 | \*---------------------------------------------------------------------------*/ | 222 | \*---------------------------------------------------------------------------*/ |
232 | 223 | ||
233 | void mag_to_phase(float phase[], /* Nfft/2+1 output phase samples in radians */ | 224 | void mag_to_phase( |
234 | float Gdbfk[], /* Nfft/2+1 postive freq amplitudes samples in dB */ | 225 | float phase[], /* Nfft/2+1 output phase samples in radians */ |
235 | int Nfft, | 226 | float Gdbfk[], /* Nfft/2+1 positive freq amplitudes samples in dB */ |
236 | codec2_fft_cfg fft_fwd_cfg, | 227 | int Nfft, codec2_fft_cfg fft_fwd_cfg, codec2_fft_cfg fft_inv_cfg) { |
237 | codec2_fft_cfg fft_inv_cfg | 228 | COMP Sdb[Nfft], c[Nfft], cf[Nfft], Cf[Nfft]; |
238 | ) | 229 | int Ns = Nfft / 2 + 1; |
239 | { | 230 | int i; |
240 | COMP Sdb[Nfft], c[Nfft], cf[Nfft], Cf[Nfft]; | 231 | |
241 | int Ns = Nfft/2+1; | 232 | /* install negative frequency components, 1/Nfft takes into |
242 | int i; | 233 | account kiss fft lack of scaling on ifft */ |
243 | 234 | ||
244 | /* install negative frequency components, 1/Nfft takes into | 235 | Sdb[0].real = Gdbfk[0]; |
245 | account kiss fft lack of scaling on ifft */ | 236 | Sdb[0].imag = 0.0; |
246 | 237 | for (i = 1; i < Ns; i++) { | |
247 | Sdb[0].real = Gdbfk[0]; | 238 | Sdb[i].real = Sdb[Nfft - i].real = Gdbfk[i]; |
248 | Sdb[0].imag = 0.0; | 239 | Sdb[i].imag = Sdb[Nfft - i].imag = 0.0; |
249 | for(i=1; i<Ns; i++) { | 240 | } |
250 | Sdb[i].real = Sdb[Nfft-i].real = Gdbfk[i]; | 241 | |
251 | Sdb[i].imag = Sdb[Nfft-i].imag = 0.0; | 242 | /* compute real cepstrum from log magnitude spectrum */ |
252 | } | 243 | |
253 | 244 | codec2_fft(fft_inv_cfg, Sdb, c); | |
254 | /* compute real cepstrum from log magnitude spectrum */ | 245 | for (i = 0; i < Nfft; i++) { |
255 | 246 | c[i].real /= (float)Nfft; | |
256 | codec2_fft(fft_inv_cfg, Sdb, c); | 247 | c[i].imag /= (float)Nfft; |
257 | for(i=0; i<Nfft; i++) { | 248 | } |
258 | c[i].real /= (float)Nfft; | 249 | |
259 | c[i].imag /= (float)Nfft; | 250 | /* Fold cepstrum to reflect non-min-phase zeros inside unit circle */ |
260 | } | 251 | |
261 | 252 | cf[0] = c[0]; | |
262 | /* Fold cepstrum to reflect non-min-phase zeros inside unit circle */ | 253 | for (i = 1; i < Ns - 1; i++) { |
263 | 254 | cf[i] = cadd(c[i], c[Nfft - i]); | |
264 | cf[0] = c[0]; | 255 | } |
265 | for(i=1; i<Ns-1; i++) { | 256 | cf[Ns - 1] = c[Ns - 1]; |
266 | cf[i] = cadd(c[i],c[Nfft-i]); | 257 | for (i = Ns; i < Nfft; i++) { |
267 | } | 258 | cf[i].real = 0.0; |
268 | cf[Ns-1] = c[Ns-1]; | 259 | cf[i].imag = 0.0; |
269 | for(i=Ns; i<Nfft; i++) { | 260 | } |
270 | cf[i].real = 0.0; | 261 | |
271 | cf[i].imag = 0.0; | 262 | /* Cf = dB_magnitude + j * minimum_phase */ |
272 | } | 263 | |
273 | 264 | codec2_fft(fft_fwd_cfg, cf, Cf); | |
274 | /* Cf = dB_magnitude + j * minimum_phase */ | 265 | |
275 | 266 | /* The maths says we are meant to be using log(x), not 20*log10(x), | |
276 | codec2_fft(fft_fwd_cfg, cf, Cf); | 267 | so we need to scale the phase to account for this: |
277 | 268 | log(x) = 20*log10(x)/scale */ | |
278 | /* The maths says we are meant to be using log(x), not 20*log10(x), | 269 | |
279 | so we need to scale the phase to account for this: | 270 | float scale = (20.0 / logf(10.0)); |
280 | log(x) = 20*log10(x)/scale */ | 271 | |
281 | 272 | for (i = 0; i < Ns; i++) { | |
282 | float scale = (20.0/logf(10.0)); | 273 | phase[i] = Cf[i].imag / scale; |
283 | 274 | } | |
284 | for(i=0; i<Ns; i++) { | ||
285 | phase[i] = Cf[i].imag/scale; | ||
286 | } | ||
287 | |||
288 | |||
289 | } | 275 | } |
@@ -32,8 +32,10 @@ | |||
32 | #include "comp.h" | 32 | #include "comp.h" |
33 | 33 | ||
34 | void sample_phase(MODEL *model, COMP filter_phase[], COMP A[]); | 34 | void sample_phase(MODEL *model, COMP filter_phase[], COMP A[]); |
35 | void phase_synth_zero_order(int n_samp, MODEL *model, float *ex_phase, COMP filter_phase[]); | 35 | void phase_synth_zero_order(int n_samp, MODEL *model, float *ex_phase, |
36 | COMP filter_phase[]); | ||
36 | 37 | ||
37 | void mag_to_phase(float phase[], float Gdbfk[], int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); | 38 | void mag_to_phase(float phase[], float Gdbfk[], int Nfft, |
39 | codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); | ||
38 | 40 | ||
39 | #endif | 41 | #endif |
diff --git a/postfilter.c b/postfilter.c index 6542c7c..e46d488 100644 --- a/postfilter.c +++ b/postfilter.c | |||
@@ -27,16 +27,17 @@ | |||
27 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 27 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "postfilter.h" | ||
31 | |||
30 | #include <assert.h> | 32 | #include <assert.h> |
31 | #include <stdlib.h> | ||
32 | #include <stdio.h> | ||
33 | #include <math.h> | 33 | #include <math.h> |
34 | #include <stdio.h> | ||
35 | #include <stdlib.h> | ||
34 | 36 | ||
35 | #include "defines.h" | ||
36 | #include "comp.h" | 37 | #include "comp.h" |
38 | #include "defines.h" | ||
37 | #include "dump.h" | 39 | #include "dump.h" |
38 | #include "sine.h" | 40 | #include "sine.h" |
39 | #include "postfilter.h" | ||
40 | 41 | ||
41 | /*---------------------------------------------------------------------------*\ | 42 | /*---------------------------------------------------------------------------*\ |
42 | 43 | ||
@@ -44,13 +45,14 @@ | |||
44 | 45 | ||
45 | \*---------------------------------------------------------------------------*/ | 46 | \*---------------------------------------------------------------------------*/ |
46 | 47 | ||
47 | #define BG_THRESH 40.0 /* only consider low levels signals for bg_est */ | 48 | #define BG_THRESH 40.0 /* only consider low levels signals for bg_est */ |
48 | #define BG_BETA 0.1 /* averaging filter constant */ | 49 | #define BG_BETA 0.1 /* averaging filter constant */ |
49 | #define BG_MARGIN 6.0 /* harmonics this far above BG noise are | 50 | #define BG_MARGIN \ |
50 | randomised. Helped make bg noise less | 51 | 6.0 /* harmonics this far above BG noise are \ |
51 | spikey (impulsive) for mmt1, but speech was | 52 | randomised. Helped make bg noise less \ |
52 | perhaps a little rougher. | 53 | spikey (impulsive) for mmt1, but speech was \ |
53 | */ | 54 | perhaps a little rougher. \ |
55 | */ | ||
54 | 56 | ||
55 | /*---------------------------------------------------------------------------*\ | 57 | /*---------------------------------------------------------------------------*\ |
56 | 58 | ||
@@ -82,7 +84,7 @@ | |||
82 | 1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track | 84 | 1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track |
83 | up to speech level? This would be a bad thing. | 85 | up to speech level? This would be a bad thing. |
84 | 86 | ||
85 | 2/ If background noise suddenly dissapears from the source speech does | 87 | 2/ If background noise suddenly disappears from the source speech does |
86 | estimate drop quickly? What is noise suddenly re-appears? | 88 | estimate drop quickly? What is noise suddenly re-appears? |
87 | 89 | ||
88 | 3/ Background noise with a non-flat sepctrum. Current algorithm just | 90 | 3/ Background noise with a non-flat sepctrum. Current algorithm just |
@@ -98,45 +100,39 @@ | |||
98 | 100 | ||
99 | \*---------------------------------------------------------------------------*/ | 101 | \*---------------------------------------------------------------------------*/ |
100 | 102 | ||
101 | void postfilter( | 103 | void postfilter(MODEL *model, float *bg_est) { |
102 | MODEL *model, | 104 | int m, uv; |
103 | float *bg_est | ||
104 | ) | ||
105 | { | ||
106 | int m, uv; | ||
107 | float e, thresh; | 105 | float e, thresh; |
108 | 106 | ||
109 | /* determine average energy across spectrum */ | 107 | /* determine average energy across spectrum */ |
110 | 108 | ||
111 | e = 1E-12; | 109 | e = 1E-12; |
112 | for(m=1; m<=model->L; m++) | 110 | for (m = 1; m <= model->L; m++) e += model->A[m] * model->A[m]; |
113 | e += model->A[m]*model->A[m]; | ||
114 | 111 | ||
115 | assert(e > 0.0); | 112 | assert(e > 0.0); |
116 | e = 10.0*log10f(e/model->L); | 113 | e = 10.0 * log10f(e / model->L); |
117 | 114 | ||
118 | /* If beneath threhold, update bg estimate. The idea | 115 | /* If beneath threshold, update bg estimate. The idea |
119 | of the threshold is to prevent updating during high level | 116 | of the threshold is to prevent updating during high level |
120 | speech. */ | 117 | speech. */ |
121 | 118 | ||
122 | if ((e < BG_THRESH) && !model->voiced) | 119 | if ((e < BG_THRESH) && !model->voiced) |
123 | *bg_est = *bg_est*(1.0 - BG_BETA) + e*BG_BETA; | 120 | *bg_est = *bg_est * (1.0 - BG_BETA) + e * BG_BETA; |
124 | 121 | ||
125 | /* now mess with phases during voiced frames to make any harmonics | 122 | /* now mess with phases during voiced frames to make any harmonics |
126 | less then our background estimate unvoiced. | 123 | less then our background estimate unvoiced. |
127 | */ | 124 | */ |
128 | 125 | ||
129 | uv = 0; | 126 | uv = 0; |
130 | thresh = POW10F((*bg_est + BG_MARGIN)/20.0); | 127 | thresh = POW10F((*bg_est + BG_MARGIN) / 20.0); |
131 | if (model->voiced) | 128 | if (model->voiced) |
132 | for(m=1; m<=model->L; m++) | 129 | for (m = 1; m <= model->L; m++) |
133 | if (model->A[m] < thresh) { | 130 | if (model->A[m] < thresh) { |
134 | model->phi[m] = (TWO_PI/CODEC2_RAND_MAX)*(float)codec2_rand(); | 131 | model->phi[m] = (TWO_PI / CODEC2_RAND_MAX) * (float)codec2_rand(); |
135 | uv++; | 132 | uv++; |
136 | } | 133 | } |
137 | 134 | ||
138 | #ifdef DUMP | 135 | #ifdef DUMP |
139 | dump_bg(e, *bg_est, 100.0*uv/model->L); | 136 | dump_bg(e, *bg_est, 100.0 * uv / model->L); |
140 | #endif | 137 | #endif |
141 | |||
142 | } | 138 | } |
diff --git a/postfilter.h b/postfilter.h index 156714e..ecf7f39 100644 --- a/postfilter.h +++ b/postfilter.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #ifndef __POSTFILTER__ | 28 | #ifndef __POSTFILTER__ |
29 | #define __POSTFILTER__ | 29 | #define __POSTFILTER__ |
30 | 30 | ||
31 | #include "defines.h" | ||
32 | |||
31 | void postfilter(MODEL *model, float *bg_est); | 33 | void postfilter(MODEL *model, float *bg_est); |
32 | 34 | ||
33 | #endif | 35 | #endif |
@@ -24,26 +24,27 @@ | |||
24 | 24 | ||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "quantise.h" | ||
28 | |||
27 | #include <assert.h> | 29 | #include <assert.h> |
28 | #include <ctype.h> | 30 | #include <ctype.h> |
31 | #include <math.h> | ||
29 | #include <stdio.h> | 32 | #include <stdio.h> |
30 | #include <stdlib.h> | 33 | #include <stdlib.h> |
31 | #include <string.h> | 34 | #include <string.h> |
32 | #include <math.h> | ||
33 | 35 | ||
36 | #include "codec2_fft.h" | ||
34 | #include "defines.h" | 37 | #include "defines.h" |
35 | #include "dump.h" | 38 | #include "dump.h" |
36 | #include "quantise.h" | ||
37 | #include "lpc.h" | 39 | #include "lpc.h" |
38 | #include "lsp.h" | 40 | #include "lsp.h" |
39 | #include "codec2_fft.h" | ||
40 | #include "phase.h" | ||
41 | #include "mbest.h" | 41 | #include "mbest.h" |
42 | #include "phase.h" | ||
42 | 43 | ||
43 | #undef PROFILE | 44 | #undef PROFILE |
44 | #include "machdep.h" | 45 | #include "machdep.h" |
45 | 46 | ||
46 | #define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ | 47 | #define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ |
47 | 48 | ||
48 | /*---------------------------------------------------------------------------*\ | 49 | /*---------------------------------------------------------------------------*\ |
49 | 50 | ||
@@ -52,7 +53,7 @@ | |||
52 | \*---------------------------------------------------------------------------*/ | 53 | \*---------------------------------------------------------------------------*/ |
53 | 54 | ||
54 | float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], | 55 | float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], |
55 | int m_pitch, int order); | 56 | int m_pitch, int order); |
56 | 57 | ||
57 | /*---------------------------------------------------------------------------*\ | 58 | /*---------------------------------------------------------------------------*\ |
58 | 59 | ||
@@ -60,46 +61,11 @@ float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], | |||
60 | 61 | ||
61 | \*---------------------------------------------------------------------------*/ | 62 | \*---------------------------------------------------------------------------*/ |
62 | 63 | ||
63 | int lsp_bits(int i) { | 64 | int lsp_bits(int i) { return lsp_cb[i].log2m; } |
64 | return lsp_cb[i].log2m; | ||
65 | } | ||
66 | 65 | ||
67 | int lspd_bits(int i) { | 66 | int lspd_bits(int i) { return lsp_cbd[i].log2m; } |
68 | return lsp_cbd[i].log2m; | ||
69 | } | ||
70 | 67 | ||
71 | #ifndef CORTEX_M4 | 68 | int lsp_pred_vq_bits(int i) { return lsp_cbjmv[i].log2m; } |
72 | int mel_bits(int i) { | ||
73 | return mel_cb[i].log2m; | ||
74 | } | ||
75 | |||
76 | int lspmelvq_cb_bits(int i) { | ||
77 | return lspmelvq_cb[i].log2m; | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | #ifdef __EXPERIMENTAL__ | ||
82 | int lspdt_bits(int i) { | ||
83 | return lsp_cbdt[i].log2m; | ||
84 | } | ||
85 | #endif | ||
86 | |||
87 | int lsp_pred_vq_bits(int i) { | ||
88 | return lsp_cbjvm[i].log2m; | ||
89 | } | ||
90 | |||
91 | /*---------------------------------------------------------------------------*\ | ||
92 | |||
93 | quantise_init | ||
94 | |||
95 | Loads the entire LSP quantiser comprised of several vector quantisers | ||
96 | (codebooks). | ||
97 | |||
98 | \*---------------------------------------------------------------------------*/ | ||
99 | |||
100 | void quantise_init() | ||
101 | { | ||
102 | } | ||
103 | 69 | ||
104 | /*---------------------------------------------------------------------------*\ | 70 | /*---------------------------------------------------------------------------*\ |
105 | 71 | ||
@@ -111,7 +77,7 @@ void quantise_init() | |||
111 | 77 | ||
112 | \*---------------------------------------------------------------------------*/ | 78 | \*---------------------------------------------------------------------------*/ |
113 | 79 | ||
114 | long quantise(const float * cb, float vec[], float w[], int k, int m, float *se) | 80 | long quantise(const float *cb, float vec[], float w[], int k, int m, float *se) |
115 | /* float cb[][K]; current VQ codebook */ | 81 | /* float cb[][K]; current VQ codebook */ |
116 | /* float vec[]; vector to quantise */ | 82 | /* float vec[]; vector to quantise */ |
117 | /* float w[]; weighting vector */ | 83 | /* float w[]; weighting vector */ |
@@ -119,363 +85,123 @@ long quantise(const float * cb, float vec[], float w[], int k, int m, float *se) | |||
119 | /* int m; size of codebook */ | 85 | /* int m; size of codebook */ |
120 | /* float *se; accumulated squared error */ | 86 | /* float *se; accumulated squared error */ |
121 | { | 87 | { |
122 | float e; /* current error */ | 88 | float e; /* current error */ |
123 | long besti; /* best index so far */ | 89 | long besti; /* best index so far */ |
124 | float beste; /* best error so far */ | 90 | float beste; /* best error so far */ |
125 | long j; | 91 | long j; |
126 | int i; | 92 | int i; |
127 | float diff; | 93 | float diff; |
128 | |||
129 | besti = 0; | ||
130 | beste = 1E32; | ||
131 | for(j=0; j<m; j++) { | ||
132 | e = 0.0; | ||
133 | for(i=0; i<k; i++) { | ||
134 | diff = cb[j*k+i]-vec[i]; | ||
135 | e += (diff*w[i] * diff*w[i]); | ||
136 | } | ||
137 | if (e < beste) { | ||
138 | beste = e; | ||
139 | besti = j; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | *se += beste; | ||
144 | |||
145 | return(besti); | ||
146 | } | ||
147 | |||
148 | |||
149 | |||
150 | /*---------------------------------------------------------------------------*\ | ||
151 | |||
152 | encode_lspds_scalar() | ||
153 | |||
154 | Scalar/VQ LSP difference quantiser. | ||
155 | |||
156 | \*---------------------------------------------------------------------------*/ | ||
157 | 94 | ||
158 | void encode_lspds_scalar( | 95 | besti = 0; |
159 | int indexes[], | 96 | beste = 1E32; |
160 | float lsp[], | 97 | for (j = 0; j < m; j++) { |
161 | int order | 98 | e = 0.0; |
162 | ) | 99 | for (i = 0; i < k; i++) { |
163 | { | 100 | diff = cb[j * k + i] - vec[i]; |
164 | int i,k,m; | 101 | e += (diff * w[i] * diff * w[i]); |
165 | float lsp_hz[order]; | ||
166 | float lsp__hz[order]; | ||
167 | float dlsp[order]; | ||
168 | float dlsp_[order]; | ||
169 | float wt[order]; | ||
170 | const float *cb; | ||
171 | float se; | ||
172 | |||
173 | for(i=0; i<order; i++) { | ||
174 | wt[i] = 1.0; | ||
175 | } | 102 | } |
176 | 103 | if (e < beste) { | |
177 | /* convert from radians to Hz so we can use human readable | 104 | beste = e; |
178 | frequencies */ | 105 | besti = j; |
179 | |||
180 | for(i=0; i<order; i++) | ||
181 | lsp_hz[i] = (4000.0/PI)*lsp[i]; | ||
182 | |||
183 | //printf("\n"); | ||
184 | |||
185 | wt[0] = 1.0; | ||
186 | for(i=0; i<order; i++) { | ||
187 | |||
188 | /* find difference from previous qunatised lsp */ | ||
189 | |||
190 | if (i) | ||
191 | dlsp[i] = lsp_hz[i] - lsp__hz[i-1]; | ||
192 | else | ||
193 | dlsp[0] = lsp_hz[0]; | ||
194 | |||
195 | k = lsp_cbd[i].k; | ||
196 | m = lsp_cbd[i].m; | ||
197 | cb = lsp_cbd[i].cb; | ||
198 | indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se); | ||
199 | dlsp_[i] = cb[indexes[i]*k]; | ||
200 | |||
201 | |||
202 | if (i) | ||
203 | lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; | ||
204 | else | ||
205 | lsp__hz[0] = dlsp_[0]; | ||
206 | |||
207 | //printf("%d lsp %3.2f dlsp %3.2f dlsp_ %3.2f lsp_ %3.2f\n", i, lsp_hz[i], dlsp[i], dlsp_[i], lsp__hz[i]); | ||
208 | } | 106 | } |
107 | } | ||
209 | 108 | ||
210 | } | 109 | *se += beste; |
211 | |||
212 | |||
213 | void decode_lspds_scalar( | ||
214 | float lsp_[], | ||
215 | int indexes[], | ||
216 | int order | ||
217 | ) | ||
218 | { | ||
219 | int i,k; | ||
220 | float lsp__hz[order]; | ||
221 | float dlsp_[order]; | ||
222 | const float *cb; | ||
223 | |||
224 | for(i=0; i<order; i++) { | ||
225 | |||
226 | k = lsp_cbd[i].k; | ||
227 | cb = lsp_cbd[i].cb; | ||
228 | dlsp_[i] = cb[indexes[i]*k]; | ||
229 | |||
230 | if (i) | ||
231 | lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; | ||
232 | else | ||
233 | lsp__hz[0] = dlsp_[0]; | ||
234 | |||
235 | lsp_[i] = (PI/4000.0)*lsp__hz[i]; | ||
236 | |||
237 | //printf("%d dlsp_ %3.2f lsp_ %3.2f\n", i, dlsp_[i], lsp__hz[i]); | ||
238 | } | ||
239 | 110 | ||
111 | return (besti); | ||
240 | } | 112 | } |
241 | 113 | ||
242 | #ifdef __EXPERIMENTAL__ | ||
243 | /*---------------------------------------------------------------------------*\ | 114 | /*---------------------------------------------------------------------------*\ |
244 | 115 | ||
245 | lspvq_quantise | 116 | encode_lspds_scalar() |
246 | 117 | ||
247 | Vector LSP quantiser. | 118 | Scalar/VQ LSP difference-in-frequency quantiser. |
248 | 119 | ||
249 | \*---------------------------------------------------------------------------*/ | 120 | \*---------------------------------------------------------------------------*/ |
250 | 121 | ||
251 | void lspvq_quantise( | 122 | void encode_lspds_scalar(int indexes[], float lsp[], int order) { |
252 | float lsp[], | 123 | int i, k, m; |
253 | float lsp_[], | 124 | float lsp_hz[order]; |
254 | int order | 125 | float lsp__hz[order]; |
255 | ) | 126 | float dlsp[order]; |
256 | { | 127 | float dlsp_[order]; |
257 | int i,k,m,ncb, nlsp; | 128 | float wt[order]; |
258 | float wt[order], lsp_hz[order]; | 129 | const float *cb; |
259 | const float *cb; | 130 | float se; |
260 | float se; | 131 | |
261 | int index; | 132 | for (i = 0; i < order; i++) { |
262 | 133 | wt[i] = 1.0; | |
263 | for(i=0; i<order; i++) { | 134 | } |
264 | wt[i] = 1.0; | ||
265 | lsp_hz[i] = 4000.0*lsp[i]/PI; | ||
266 | } | ||
267 | |||
268 | /* scalar quantise LSPs 1,2,3,4 */ | ||
269 | |||
270 | /* simple uniform scalar quantisers */ | ||
271 | |||
272 | for(i=0; i<4; i++) { | ||
273 | k = lsp_cb[i].k; | ||
274 | m = lsp_cb[i].m; | ||
275 | cb = lsp_cb[i].cb; | ||
276 | index = quantise(cb, &lsp_hz[i], wt, k, m, &se); | ||
277 | lsp_[i] = cb[index*k]*PI/4000.0; | ||
278 | } | ||
279 | |||
280 | //#define WGHT | ||
281 | #ifdef WGHT | ||
282 | for(i=4; i<9; i++) { | ||
283 | wt[i] = 1.0/(lsp[i]-lsp[i-1]) + 1.0/(lsp[i+1]-lsp[i]); | ||
284 | //printf("wt[%d] = %f\n", i, wt[i]); | ||
285 | } | ||
286 | wt[9] = 1.0/(lsp[i]-lsp[i-1]); | ||
287 | #endif | ||
288 | |||
289 | /* VQ LSPs 5,6,7,8,9,10 */ | ||
290 | |||
291 | ncb = 4; | ||
292 | nlsp = 4; | ||
293 | k = lsp_cbjnd[ncb].k; | ||
294 | m = lsp_cbjnd[ncb].m; | ||
295 | cb = lsp_cbjnd[ncb].cb; | ||
296 | index = quantise(cb, &lsp_hz[nlsp], &wt[nlsp], k, m, &se); | ||
297 | for(i=4; i<order; i++) { | ||
298 | lsp_[i] = cb[index*k+i-4]*(PI/4000.0); | ||
299 | //printf("%4.f (%4.f) ", lsp_hz[i], cb[index*k+i-4]); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | /*---------------------------------------------------------------------------*\ | ||
304 | |||
305 | lspjnd_quantise | ||
306 | 135 | ||
307 | Experimental JND LSP quantiser. | 136 | /* convert from radians to Hz so we can use human readable |
137 | frequencies */ | ||
308 | 138 | ||
309 | \*---------------------------------------------------------------------------*/ | 139 | for (i = 0; i < order; i++) lsp_hz[i] = (4000.0 / PI) * lsp[i]; |
310 | 140 | ||
311 | void lspjnd_quantise(float lsps[], float lsps_[], int order) | 141 | wt[0] = 1.0; |
312 | { | 142 | for (i = 0; i < order; i++) { |
313 | int i,k,m; | 143 | /* find difference from previous quantised lsp */ |
314 | float wt[order], lsps_hz[order]; | ||
315 | const float *cb; | ||
316 | float se = 0.0; | ||
317 | int index; | ||
318 | |||
319 | for(i=0; i<order; i++) { | ||
320 | wt[i] = 1.0; | ||
321 | } | ||
322 | |||
323 | /* convert to Hz */ | ||
324 | 144 | ||
325 | for(i=0; i<order; i++) { | 145 | if (i) |
326 | lsps_hz[i] = lsps[i]*(4000.0/PI); | 146 | dlsp[i] = lsp_hz[i] - lsp__hz[i - 1]; |
327 | lsps_[i] = lsps[i]; | 147 | else |
328 | } | 148 | dlsp[0] = lsp_hz[0]; |
329 | 149 | ||
330 | /* simple uniform scalar quantisers */ | 150 | k = lsp_cbd[i].k; |
151 | m = lsp_cbd[i].m; | ||
152 | cb = lsp_cbd[i].cb; | ||
153 | indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se); | ||
154 | dlsp_[i] = cb[indexes[i] * k]; | ||
331 | 155 | ||
332 | for(i=0; i<4; i++) { | 156 | if (i) |
333 | k = lsp_cbjnd[i].k; | 157 | lsp__hz[i] = lsp__hz[i - 1] + dlsp_[i]; |
334 | m = lsp_cbjnd[i].m; | 158 | else |
335 | cb = lsp_cbjnd[i].cb; | 159 | lsp__hz[0] = dlsp_[0]; |
336 | index = quantise(cb, &lsps_hz[i], wt, k, m, &se); | 160 | } |
337 | lsps_[i] = cb[index*k]*(PI/4000.0); | ||
338 | } | ||
339 | |||
340 | /* VQ LSPs 5,6,7,8,9,10 */ | ||
341 | |||
342 | k = lsp_cbjnd[4].k; | ||
343 | m = lsp_cbjnd[4].m; | ||
344 | cb = lsp_cbjnd[4].cb; | ||
345 | index = quantise(cb, &lsps_hz[4], &wt[4], k, m, &se); | ||
346 | //printf("k = %d m = %d c[0] %f cb[k] %f\n", k,m,cb[0],cb[k]); | ||
347 | //printf("index = %4d: ", index); | ||
348 | for(i=4; i<order; i++) { | ||
349 | lsps_[i] = cb[index*k+i-4]*(PI/4000.0); | ||
350 | //printf("%4.f (%4.f) ", lsps_hz[i], cb[index*k+i-4]); | ||
351 | } | ||
352 | //printf("\n"); | ||
353 | } | 161 | } |
354 | 162 | ||
355 | void compute_weights(const float *x, float *w, int ndim); | 163 | void decode_lspds_scalar(float lsp_[], int indexes[], int order) { |
356 | 164 | int i, k; | |
357 | /*---------------------------------------------------------------------------*\ | 165 | float lsp__hz[order]; |
358 | 166 | float dlsp_[order]; | |
359 | lspdt_quantise | 167 | const float *cb; |
360 | |||
361 | LSP difference in time quantiser. Split VQ, encoding LSPs 1-4 with | ||
362 | one VQ, and LSPs 5-10 with a second. Update of previous lsp memory | ||
363 | is done outside of this function to handle dT between 10 or 20ms | ||
364 | frames. | ||
365 | |||
366 | mode action | ||
367 | ------------------ | ||
368 | |||
369 | LSPDT_ALL VQ LSPs 1-4 and 5-10 | ||
370 | LSPDT_LOW Just VQ LSPs 1-4, for LSPs 5-10 just copy previous | ||
371 | LSPDT_HIGH Just VQ LSPs 5-10, for LSPs 1-4 just copy previous | ||
372 | |||
373 | \*---------------------------------------------------------------------------*/ | ||
374 | |||
375 | void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode) | ||
376 | { | ||
377 | int i; | ||
378 | float wt[LPC_ORD]; | ||
379 | float lsps_dt[LPC_ORD]; | ||
380 | #ifdef TRY_LSPDT_VQ | ||
381 | int k,m; | ||
382 | int index; | ||
383 | const float *cb; | ||
384 | float se = 0.0; | ||
385 | #endif // TRY_LSPDT_VQ | ||
386 | |||
387 | //compute_weights(lsps, wt, LPC_ORD); | ||
388 | for(i=0; i<LPC_ORD; i++) { | ||
389 | wt[i] = 1.0; | ||
390 | } | ||
391 | |||
392 | //compute_weights(lsps, wt, LPC_ORD ); | ||
393 | 168 | ||
394 | for(i=0; i<LPC_ORD; i++) { | 169 | for (i = 0; i < order; i++) { |
395 | lsps_dt[i] = lsps[i] - lsps__prev[i]; | 170 | k = lsp_cbd[i].k; |
396 | lsps_[i] = lsps__prev[i]; | 171 | cb = lsp_cbd[i].cb; |
397 | } | 172 | dlsp_[i] = cb[indexes[i] * k]; |
398 | 173 | ||
399 | //#define TRY_LSPDT_VQ | 174 | if (i) |
400 | #ifdef TRY_LSPDT_VQ | 175 | lsp__hz[i] = lsp__hz[i - 1] + dlsp_[i]; |
401 | /* this actually improves speech a bit, but 40ms updates works surprsingly well.... */ | 176 | else |
402 | k = lsp_cbdt[0].k; | 177 | lsp__hz[0] = dlsp_[0]; |
403 | m = lsp_cbdt[0].m; | ||
404 | cb = lsp_cbdt[0].cb; | ||
405 | index = quantise(cb, lsps_dt, wt, k, m, &se); | ||
406 | for(i=0; i<LPC_ORD; i++) { | ||
407 | lsps_[i] += cb[index*k + i]; | ||
408 | } | ||
409 | #endif | ||
410 | 178 | ||
179 | lsp_[i] = (PI / 4000.0) * lsp__hz[i]; | ||
180 | } | ||
411 | } | 181 | } |
412 | #endif | ||
413 | 182 | ||
414 | #define MIN(a,b) ((a)<(b)?(a):(b)) | 183 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
415 | #define MAX_ENTRIES 16384 | 184 | #define MAX_ENTRIES 16384 |
416 | 185 | ||
417 | void compute_weights(const float *x, float *w, int ndim) | 186 | void compute_weights(const float *x, float *w, int ndim) { |
418 | { | ||
419 | int i; | 187 | int i; |
420 | w[0] = MIN(x[0], x[1]-x[0]); | 188 | w[0] = MIN(x[0], x[1] - x[0]); |
421 | for (i=1;i<ndim-1;i++) | 189 | for (i = 1; i < ndim - 1; i++) w[i] = MIN(x[i] - x[i - 1], x[i + 1] - x[i]); |
422 | w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]); | 190 | w[ndim - 1] = MIN(x[ndim - 1] - x[ndim - 2], PI - x[ndim - 1]); |
423 | w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]); | ||
424 | |||
425 | for (i=0;i<ndim;i++) | ||
426 | w[i] = 1./(.01+w[i]); | ||
427 | //w[0]*=3; | ||
428 | //w[1]*=2; | ||
429 | } | ||
430 | |||
431 | #ifdef __EXPERIMENTAL__ | ||
432 | /* LSP weight calculation ported from m-file function kindly submitted | ||
433 | by Anssi, OH3GDD */ | ||
434 | 191 | ||
435 | void compute_weights_anssi_mode2(const float *x, float *w, int ndim) | 192 | for (i = 0; i < ndim; i++) w[i] = 1. / (.01 + w[i]); |
436 | { | ||
437 | int i; | ||
438 | float d[LPC_ORD]; | ||
439 | |||
440 | assert(ndim == LPC_ORD); | ||
441 | |||
442 | for(i=0; i<LPC_ORD; i++) | ||
443 | d[i] = 1.0; | ||
444 | |||
445 | d[0] = x[1]; | ||
446 | for (i=1; i<LPC_ORD-1; i++) | ||
447 | d[i] = x[i+1] - x[i-1]; | ||
448 | d[LPC_ORD-1] = PI - x[8]; | ||
449 | for (i=0; i<LPC_ORD; i++) { | ||
450 | if (x[i]<((400.0/4000.0)*PI)) | ||
451 | w[i]=5.0/(0.01+d[i]); | ||
452 | else if (x[i]<((700.0/4000.0)*PI)) | ||
453 | w[i]=4.0/(0.01+d[i]); | ||
454 | else if (x[i]<((1200.0/4000.0)*PI)) | ||
455 | w[i]=3.0/(0.01+d[i]); | ||
456 | else if (x[i]<((2000.0/4000.0)*PI)) | ||
457 | w[i]=2.0/(0.01+d[i]); | ||
458 | else | ||
459 | w[i]=1.0/(0.01+d[i]); | ||
460 | |||
461 | w[i]=powf(w[i]+0.3, 0.66); | ||
462 | } | ||
463 | } | 193 | } |
464 | #endif | ||
465 | 194 | ||
466 | int find_nearest(const float *codebook, int nb_entries, float *x, int ndim) | 195 | int find_nearest(const float *codebook, int nb_entries, float *x, int ndim) { |
467 | { | ||
468 | int i, j; | 196 | int i, j; |
469 | float min_dist = 1e15; | 197 | float min_dist = 1e15; |
470 | int nearest = 0; | 198 | int nearest = 0; |
471 | 199 | ||
472 | for (i=0;i<nb_entries;i++) | 200 | for (i = 0; i < nb_entries; i++) { |
473 | { | 201 | float dist = 0; |
474 | float dist=0; | 202 | for (j = 0; j < ndim; j++) |
475 | for (j=0;j<ndim;j++) | 203 | dist += (x[j] - codebook[i * ndim + j]) * (x[j] - codebook[i * ndim + j]); |
476 | dist += (x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]); | 204 | if (dist < min_dist) { |
477 | if (dist<min_dist) | ||
478 | { | ||
479 | min_dist = dist; | 205 | min_dist = dist; |
480 | nearest = i; | 206 | nearest = i; |
481 | } | 207 | } |
@@ -483,19 +209,18 @@ int find_nearest(const float *codebook, int nb_entries, float *x, int ndim) | |||
483 | return nearest; | 209 | return nearest; |
484 | } | 210 | } |
485 | 211 | ||
486 | int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim) | 212 | int find_nearest_weighted(const float *codebook, int nb_entries, float *x, |
487 | { | 213 | const float *w, int ndim) { |
488 | int i, j; | 214 | int i, j; |
489 | float min_dist = 1e15; | 215 | float min_dist = 1e15; |
490 | int nearest = 0; | 216 | int nearest = 0; |
491 | 217 | ||
492 | for (i=0;i<nb_entries;i++) | 218 | for (i = 0; i < nb_entries; i++) { |
493 | { | 219 | float dist = 0; |
494 | float dist=0; | 220 | for (j = 0; j < ndim; j++) |
495 | for (j=0;j<ndim;j++) | 221 | dist += w[j] * (x[j] - codebook[i * ndim + j]) * |
496 | dist += w[j]*(x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]); | 222 | (x[j] - codebook[i * ndim + j]); |
497 | if (dist<min_dist) | 223 | if (dist < min_dist) { |
498 | { | ||
499 | min_dist = dist; | 224 | min_dist = dist; |
500 | nearest = i; | 225 | nearest = i; |
501 | } | 226 | } |
@@ -503,212 +228,74 @@ int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const | |||
503 | return nearest; | 228 | return nearest; |
504 | } | 229 | } |
505 | 230 | ||
506 | void lspjvm_quantise(float *x, float *xq, int order) | 231 | void lspjmv_quantise(float *x, float *xq, int order) { |
507 | { | ||
508 | int i, n1, n2, n3; | 232 | int i, n1, n2, n3; |
509 | float err[order], err2[order], err3[order]; | 233 | float err[order], err2[order], err3[order]; |
510 | float w[order], w2[order], w3[order]; | 234 | float w[order], w2[order], w3[order]; |
511 | const float *codebook1 = lsp_cbjvm[0].cb; | 235 | const float *codebook1 = lsp_cbjmv[0].cb; |
512 | const float *codebook2 = lsp_cbjvm[1].cb; | 236 | const float *codebook2 = lsp_cbjmv[1].cb; |
513 | const float *codebook3 = lsp_cbjvm[2].cb; | 237 | const float *codebook3 = lsp_cbjmv[2].cb; |
514 | 238 | ||
515 | w[0] = MIN(x[0], x[1]-x[0]); | 239 | w[0] = MIN(x[0], x[1] - x[0]); |
516 | for (i=1;i<order-1;i++) | 240 | for (i = 1; i < order - 1; i++) w[i] = MIN(x[i] - x[i - 1], x[i + 1] - x[i]); |
517 | w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]); | 241 | w[order - 1] = MIN(x[order - 1] - x[order - 2], PI - x[order - 1]); |
518 | w[order-1] = MIN(x[order-1]-x[order-2], PI-x[order-1]); | ||
519 | 242 | ||
520 | compute_weights(x, w, order); | 243 | compute_weights(x, w, order); |
521 | 244 | ||
522 | n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, order); | 245 | n1 = find_nearest(codebook1, lsp_cbjmv[0].m, x, order); |
523 | 246 | ||
524 | for (i=0;i<order;i++) | 247 | for (i = 0; i < order; i++) { |
525 | { | 248 | xq[i] = codebook1[order * n1 + i]; |
526 | xq[i] = codebook1[order*n1+i]; | ||
527 | err[i] = x[i] - xq[i]; | 249 | err[i] = x[i] - xq[i]; |
528 | } | 250 | } |
529 | for (i=0;i<order/2;i++) | 251 | for (i = 0; i < order / 2; i++) { |
530 | { | 252 | err2[i] = err[2 * i]; |
531 | err2[i] = err[2*i]; | 253 | err3[i] = err[2 * i + 1]; |
532 | err3[i] = err[2*i+1]; | 254 | w2[i] = w[2 * i]; |
533 | w2[i] = w[2*i]; | 255 | w3[i] = w[2 * i + 1]; |
534 | w3[i] = w[2*i+1]; | ||
535 | } | 256 | } |
536 | n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, order/2); | 257 | n2 = find_nearest_weighted(codebook2, lsp_cbjmv[1].m, err2, w2, order / 2); |
537 | n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, order/2); | 258 | n3 = find_nearest_weighted(codebook3, lsp_cbjmv[2].m, err3, w3, order / 2); |
538 | 259 | ||
539 | for (i=0;i<order/2;i++) | 260 | for (i = 0; i < order / 2; i++) { |
540 | { | 261 | xq[2 * i] += codebook2[order * n2 / 2 + i]; |
541 | xq[2*i] += codebook2[order*n2/2+i]; | 262 | xq[2 * i + 1] += codebook3[order * n3 / 2 + i]; |
542 | xq[2*i+1] += codebook3[order*n3/2+i]; | ||
543 | } | 263 | } |
544 | } | 264 | } |
545 | 265 | ||
266 | int check_lsp_order(float lsp[], int order) { | ||
267 | int i; | ||
268 | float tmp; | ||
269 | int swaps = 0; | ||
270 | |||
271 | for (i = 1; i < order; i++) | ||
272 | if (lsp[i] < lsp[i - 1]) { | ||
273 | // fprintf(stderr, "swap %d\n",i); | ||
274 | swaps++; | ||
275 | tmp = lsp[i - 1]; | ||
276 | lsp[i - 1] = lsp[i] - 0.1; | ||
277 | lsp[i] = tmp + 0.1; | ||
278 | i = 1; /* start check again, as swap may have caused out of order */ | ||
279 | } | ||
546 | 280 | ||
547 | #ifndef CORTEX_M4 | 281 | return swaps; |
548 | /* simple (non mbest) 6th order LSP MEL VQ quantiser. Returns MSE of result */ | ||
549 | |||
550 | float lspmelvq_quantise(float *x, float *xq, int order) | ||
551 | { | ||
552 | int i, n1, n2, n3; | ||
553 | float err[order]; | ||
554 | const float *codebook1 = lspmelvq_cb[0].cb; | ||
555 | const float *codebook2 = lspmelvq_cb[1].cb; | ||
556 | const float *codebook3 = lspmelvq_cb[2].cb; | ||
557 | float tmp[order]; | ||
558 | float mse; | ||
559 | |||
560 | assert(order == lspmelvq_cb[0].k); | ||
561 | |||
562 | n1 = find_nearest(codebook1, lspmelvq_cb[0].m, x, order); | ||
563 | |||
564 | for (i=0; i<order; i++) { | ||
565 | tmp[i] = codebook1[order*n1+i]; | ||
566 | err[i] = x[i] - tmp[i]; | ||
567 | } | ||
568 | |||
569 | n2 = find_nearest(codebook2, lspmelvq_cb[1].m, err, order); | ||
570 | |||
571 | for (i=0; i<order; i++) { | ||
572 | tmp[i] += codebook2[order*n2+i]; | ||
573 | err[i] = x[i] - tmp[i]; | ||
574 | } | ||
575 | |||
576 | n3 = find_nearest(codebook3, lspmelvq_cb[2].m, err, order); | ||
577 | |||
578 | mse = 0.0; | ||
579 | for (i=0; i<order; i++) { | ||
580 | tmp[i] += codebook3[order*n3+i]; | ||
581 | err[i] = x[i] - tmp[i]; | ||
582 | mse += err[i]*err[i]; | ||
583 | } | ||
584 | |||
585 | for (i=0; i<order; i++) { | ||
586 | xq[i] = tmp[i]; | ||
587 | } | ||
588 | |||
589 | return mse; | ||
590 | } | ||
591 | |||
592 | /* 3 stage VQ LSP quantiser useing mbest search. Design and guidance kindly submitted by Anssi, OH3GDD */ | ||
593 | |||
594 | float lspmelvq_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries) | ||
595 | { | ||
596 | int i, j, n1, n2, n3; | ||
597 | const float *codebook1 = lspmelvq_cb[0].cb; | ||
598 | const float *codebook2 = lspmelvq_cb[1].cb; | ||
599 | const float *codebook3 = lspmelvq_cb[2].cb; | ||
600 | struct MBEST *mbest_stage1, *mbest_stage2, *mbest_stage3; | ||
601 | float target[ndim]; | ||
602 | float w[ndim]; | ||
603 | int index[MBEST_STAGES]; | ||
604 | float mse, tmp; | ||
605 | |||
606 | for(i=0; i<ndim; i++) | ||
607 | w[i] = 1.0; | ||
608 | |||
609 | mbest_stage1 = mbest_create(mbest_entries); | ||
610 | mbest_stage2 = mbest_create(mbest_entries); | ||
611 | mbest_stage3 = mbest_create(mbest_entries); | ||
612 | for(i=0; i<MBEST_STAGES; i++) | ||
613 | index[i] = 0; | ||
614 | |||
615 | /* Stage 1 */ | ||
616 | |||
617 | mbest_search(codebook1, x, w, ndim, lspmelvq_cb[0].m, mbest_stage1, index); | ||
618 | MBEST_PRINT("Stage 1:", mbest_stage1); | ||
619 | |||
620 | /* Stage 2 */ | ||
621 | |||
622 | for (j=0; j<mbest_entries; j++) { | ||
623 | index[1] = n1 = mbest_stage1->list[j].index[0]; | ||
624 | for(i=0; i<ndim; i++) | ||
625 | target[i] = x[i] - codebook1[ndim*n1+i]; | ||
626 | mbest_search(codebook2, target, w, ndim, lspmelvq_cb[1].m, mbest_stage2, index); | ||
627 | } | ||
628 | MBEST_PRINT("Stage 2:", mbest_stage2); | ||
629 | |||
630 | /* Stage 3 */ | ||
631 | |||
632 | for (j=0; j<mbest_entries; j++) { | ||
633 | index[2] = n1 = mbest_stage2->list[j].index[1]; | ||
634 | index[1] = n2 = mbest_stage2->list[j].index[0]; | ||
635 | for(i=0; i<ndim; i++) | ||
636 | target[i] = x[i] - codebook1[ndim*n1+i] - codebook2[ndim*n2+i]; | ||
637 | mbest_search(codebook3, target, w, ndim, lspmelvq_cb[2].m, mbest_stage3, index); | ||
638 | } | ||
639 | MBEST_PRINT("Stage 3:", mbest_stage3); | ||
640 | |||
641 | n1 = mbest_stage3->list[0].index[2]; | ||
642 | n2 = mbest_stage3->list[0].index[1]; | ||
643 | n3 = mbest_stage3->list[0].index[0]; | ||
644 | mse = 0.0; | ||
645 | for (i=0;i<ndim;i++) { | ||
646 | tmp = codebook1[ndim*n1+i] + codebook2[ndim*n2+i] + codebook3[ndim*n3+i]; | ||
647 | mse += (x[i]-tmp)*(x[i]-tmp); | ||
648 | xq[i] = tmp; | ||
649 | } | ||
650 | |||
651 | mbest_destroy(mbest_stage1); | ||
652 | mbest_destroy(mbest_stage2); | ||
653 | mbest_destroy(mbest_stage3); | ||
654 | |||
655 | indexes[0] = n1; indexes[1] = n2; indexes[2] = n3; | ||
656 | |||
657 | return mse; | ||
658 | } | ||
659 | |||
660 | |||
661 | void lspmelvq_decode(int *indexes, float *xq, int ndim) | ||
662 | { | ||
663 | int i, n1, n2, n3; | ||
664 | const float *codebook1 = lspmelvq_cb[0].cb; | ||
665 | const float *codebook2 = lspmelvq_cb[1].cb; | ||
666 | const float *codebook3 = lspmelvq_cb[2].cb; | ||
667 | |||
668 | n1 = indexes[0]; n2 = indexes[1]; n3 = indexes[2]; | ||
669 | for (i=0;i<ndim;i++) { | ||
670 | xq[i] = codebook1[ndim*n1+i] + codebook2[ndim*n2+i] + codebook3[ndim*n3+i]; | ||
671 | } | ||
672 | } | ||
673 | #endif | ||
674 | |||
675 | |||
676 | int check_lsp_order(float lsp[], int order) | ||
677 | { | ||
678 | int i; | ||
679 | float tmp; | ||
680 | int swaps = 0; | ||
681 | |||
682 | for(i=1; i<order; i++) | ||
683 | if (lsp[i] < lsp[i-1]) { | ||
684 | //fprintf(stderr, "swap %d\n",i); | ||
685 | swaps++; | ||
686 | tmp = lsp[i-1]; | ||
687 | lsp[i-1] = lsp[i]-0.1; | ||
688 | lsp[i] = tmp+0.1; | ||
689 | i = 1; /* start check again, as swap may have caused out of order */ | ||
690 | } | ||
691 | |||
692 | return swaps; | ||
693 | } | 282 | } |
694 | 283 | ||
695 | void force_min_lsp_dist(float lsp[], int order) | 284 | void force_min_lsp_dist(float lsp[], int order) { |
696 | { | 285 | int i; |
697 | int i; | ||
698 | 286 | ||
699 | for(i=1; i<order; i++) | 287 | for (i = 1; i < order; i++) |
700 | if ((lsp[i]-lsp[i-1]) < 0.01) { | 288 | if ((lsp[i] - lsp[i - 1]) < 0.01) { |
701 | lsp[i] += 0.01; | 289 | lsp[i] += 0.01; |
702 | } | 290 | } |
703 | } | 291 | } |
704 | 292 | ||
705 | |||
706 | /*---------------------------------------------------------------------------*\ | 293 | /*---------------------------------------------------------------------------*\ |
707 | 294 | ||
708 | lpc_post_filter() | 295 | lpc_post_filter() |
709 | 296 | ||
710 | Applies a post filter to the LPC synthesis filter power spectrum | 297 | Applies a post filter to the LPC synthesis filter power spectrum |
711 | Pw, which supresses the inter-formant energy. | 298 | Pw, which suppresses the inter-formant energy. |
712 | 299 | ||
713 | The algorithm is from p267 (Section 8.6) of "Digital Speech", | 300 | The algorithm is from p267 (Section 8.6) of "Digital Speech", |
714 | edited by A.M. Kondoz, 1994 published by Wiley and Sons. Chapter 8 | 301 | edited by A.M. Kondoz, 1994 published by Wiley and Sons. Chapter 8 |
@@ -722,7 +309,7 @@ void force_min_lsp_dist(float lsp[], int order) | |||
722 | it should be possible to implement this more efficiently in the | 309 | it should be possible to implement this more efficiently in the |
723 | time domain. Just not sure how to handle relative time delays | 310 | time domain. Just not sure how to handle relative time delays |
724 | between the synthesis stage and updating these coeffs. A smaller | 311 | between the synthesis stage and updating these coeffs. A smaller |
725 | FFT size might also be accetable to save CPU. | 312 | FFT size might also be acceptable to save CPU. |
726 | 313 | ||
727 | TODO: | 314 | TODO: |
728 | [ ] sync var names between Octave and C version | 315 | [ ] sync var names between Octave and C version |
@@ -733,104 +320,97 @@ void force_min_lsp_dist(float lsp[], int order) | |||
733 | \*---------------------------------------------------------------------------*/ | 320 | \*---------------------------------------------------------------------------*/ |
734 | 321 | ||
735 | void lpc_post_filter(codec2_fftr_cfg fftr_fwd_cfg, float Pw[], float ak[], | 322 | void lpc_post_filter(codec2_fftr_cfg fftr_fwd_cfg, float Pw[], float ak[], |
736 | int order, int dump, float beta, float gamma, int bass_boost, float E) | 323 | int order, int dump, float beta, float gamma, |
737 | { | 324 | int bass_boost, float E) { |
738 | int i; | 325 | int i; |
739 | float x[FFT_ENC]; /* input to FFTs */ | 326 | float x[FFT_ENC]; /* input to FFTs */ |
740 | COMP Ww[FFT_ENC/2+1]; /* weighting spectrum */ | 327 | COMP Ww[FFT_ENC / 2 + 1]; /* weighting spectrum */ |
741 | float Rw[FFT_ENC/2+1]; /* R = WA */ | 328 | float Rw[FFT_ENC / 2 + 1]; /* R = WA */ |
742 | float e_before, e_after, gain; | 329 | float e_before, e_after, gain; |
743 | float Pfw; | 330 | float Pfw; |
744 | float max_Rw, min_Rw; | 331 | float max_Rw, min_Rw; |
745 | float coeff; | 332 | float coeff; |
746 | PROFILE_VAR(tstart, tfft1, taw, tfft2, tww, tr); | 333 | PROFILE_VAR(tstart, tfft1, taw, tfft2, tww, tr); |
747 | |||
748 | PROFILE_SAMPLE(tstart); | ||
749 | |||
750 | /* Determine weighting filter spectrum W(exp(jw)) ---------------*/ | ||
751 | |||
752 | for(i=0; i<FFT_ENC; i++) { | ||
753 | x[i] = 0.0; | ||
754 | } | ||
755 | 334 | ||
756 | x[0] = ak[0]; | 335 | PROFILE_SAMPLE(tstart); |
757 | coeff = gamma; | ||
758 | for(i=1; i<=order; i++) { | ||
759 | x[i] = ak[i] * coeff; | ||
760 | coeff *= gamma; | ||
761 | } | ||
762 | codec2_fftr(fftr_fwd_cfg, x, Ww); | ||
763 | 336 | ||
764 | PROFILE_SAMPLE_AND_LOG(tfft2, taw, " fft2"); | 337 | /* Determine weighting filter spectrum W(exp(jw)) ---------------*/ |
765 | 338 | ||
766 | for(i=0; i<FFT_ENC/2; i++) { | 339 | for (i = 0; i < FFT_ENC; i++) { |
767 | Ww[i].real = Ww[i].real*Ww[i].real + Ww[i].imag*Ww[i].imag; | 340 | x[i] = 0.0; |
768 | } | 341 | } |
769 | 342 | ||
770 | PROFILE_SAMPLE_AND_LOG(tww, tfft2, " Ww"); | 343 | x[0] = ak[0]; |
344 | coeff = gamma; | ||
345 | for (i = 1; i <= order; i++) { | ||
346 | x[i] = ak[i] * coeff; | ||
347 | coeff *= gamma; | ||
348 | } | ||
349 | codec2_fftr(fftr_fwd_cfg, x, Ww); | ||
771 | 350 | ||
772 | /* Determined combined filter R = WA ---------------------------*/ | 351 | PROFILE_SAMPLE_AND_LOG(tfft2, taw, " fft2"); |
773 | 352 | ||
774 | max_Rw = 0.0; min_Rw = 1E32; | 353 | for (i = 0; i < FFT_ENC / 2; i++) { |
775 | for(i=0; i<FFT_ENC/2; i++) { | 354 | Ww[i].real = Ww[i].real * Ww[i].real + Ww[i].imag * Ww[i].imag; |
776 | Rw[i] = sqrtf(Ww[i].real * Pw[i]); | 355 | } |
777 | if (Rw[i] > max_Rw) | ||
778 | max_Rw = Rw[i]; | ||
779 | if (Rw[i] < min_Rw) | ||
780 | min_Rw = Rw[i]; | ||
781 | 356 | ||
782 | } | 357 | PROFILE_SAMPLE_AND_LOG(tww, tfft2, " Ww"); |
783 | 358 | ||
784 | PROFILE_SAMPLE_AND_LOG(tr, tww, " R"); | 359 | /* Determined combined filter R = WA ---------------------------*/ |
785 | 360 | ||
786 | #ifdef DUMP | 361 | max_Rw = 0.0; |
787 | if (dump) | 362 | min_Rw = 1E32; |
788 | dump_Rw(Rw); | 363 | for (i = 0; i < FFT_ENC / 2; i++) { |
789 | #endif | 364 | Rw[i] = sqrtf(Ww[i].real * Pw[i]); |
365 | if (Rw[i] > max_Rw) max_Rw = Rw[i]; | ||
366 | if (Rw[i] < min_Rw) min_Rw = Rw[i]; | ||
367 | } | ||
790 | 368 | ||
791 | /* create post filter mag spectrum and apply ------------------*/ | 369 | PROFILE_SAMPLE_AND_LOG(tr, tww, " R"); |
792 | 370 | ||
793 | /* measure energy before post filtering */ | 371 | #ifdef DUMP |
372 | if (dump) dump_Rw(Rw); | ||
373 | #endif | ||
794 | 374 | ||
795 | e_before = 1E-4; | 375 | /* create post filter mag spectrum and apply ------------------*/ |
796 | for(i=0; i<FFT_ENC/2; i++) | ||
797 | e_before += Pw[i]; | ||
798 | 376 | ||
799 | /* apply post filter and measure energy */ | 377 | /* measure energy before post filtering */ |
800 | 378 | ||
801 | #ifdef DUMP | 379 | e_before = 1E-4; |
802 | if (dump) | 380 | for (i = 0; i < FFT_ENC / 2; i++) e_before += Pw[i]; |
803 | dump_Pwb(Pw); | ||
804 | #endif | ||
805 | 381 | ||
382 | /* apply post filter and measure energy */ | ||
806 | 383 | ||
807 | e_after = 1E-4; | 384 | #ifdef DUMP |
808 | for(i=0; i<FFT_ENC/2; i++) { | 385 | if (dump) dump_Pwb(Pw); |
809 | Pfw = powf(Rw[i], beta); | 386 | #endif |
810 | Pw[i] *= Pfw * Pfw; | ||
811 | e_after += Pw[i]; | ||
812 | } | ||
813 | gain = e_before/e_after; | ||
814 | 387 | ||
815 | /* apply gain factor to normalise energy, and LPC Energy */ | 388 | e_after = 1E-4; |
389 | for (i = 0; i < FFT_ENC / 2; i++) { | ||
390 | Pfw = powf(Rw[i], beta); | ||
391 | Pw[i] *= Pfw * Pfw; | ||
392 | e_after += Pw[i]; | ||
393 | } | ||
394 | gain = e_before / e_after; | ||
816 | 395 | ||
817 | gain *= E; | 396 | /* apply gain factor to normalise energy, and LPC Energy */ |
818 | for(i=0; i<FFT_ENC/2; i++) { | 397 | |
819 | Pw[i] *= gain; | 398 | gain *= E; |
820 | } | 399 | for (i = 0; i < FFT_ENC / 2; i++) { |
400 | Pw[i] *= gain; | ||
401 | } | ||
821 | 402 | ||
822 | if (bass_boost) { | 403 | if (bass_boost) { |
823 | /* add 3dB to first 1 kHz to account for LP effect of PF */ | 404 | /* add 3dB to first 1 kHz to account for LP effect of PF */ |
824 | 405 | ||
825 | for(i=0; i<FFT_ENC/8; i++) { | 406 | for (i = 0; i < FFT_ENC / 8; i++) { |
826 | Pw[i] *= 1.4*1.4; | 407 | Pw[i] *= 1.4 * 1.4; |
827 | } | ||
828 | } | 408 | } |
409 | } | ||
829 | 410 | ||
830 | PROFILE_SAMPLE_AND_LOG2(tr, " filt"); | 411 | PROFILE_SAMPLE_AND_LOG2(tr, " filt"); |
831 | } | 412 | } |
832 | 413 | ||
833 | |||
834 | /*---------------------------------------------------------------------------*\ | 414 | /*---------------------------------------------------------------------------*\ |
835 | 415 | ||
836 | aks_to_M2() | 416 | aks_to_M2() |
@@ -841,134 +421,125 @@ void lpc_post_filter(codec2_fftr_cfg fftr_fwd_cfg, float Pw[], float ak[], | |||
841 | 421 | ||
842 | \*---------------------------------------------------------------------------*/ | 422 | \*---------------------------------------------------------------------------*/ |
843 | 423 | ||
844 | void aks_to_M2( | 424 | void aks_to_M2(codec2_fftr_cfg fftr_fwd_cfg, float ak[], /* LPC's */ |
845 | codec2_fftr_cfg fftr_fwd_cfg, | 425 | int order, |
846 | float ak[], /* LPC's */ | 426 | MODEL *model, /* sinusoidal model parameters for this frame */ |
847 | int order, | 427 | float E, /* energy term */ |
848 | MODEL *model, /* sinusoidal model parameters for this frame */ | 428 | float *snr, /* signal to noise ratio for this frame in dB */ |
849 | float E, /* energy term */ | 429 | int dump, /* true to dump sample to dump file */ |
850 | float *snr, /* signal to noise ratio for this frame in dB */ | 430 | int sim_pf, /* true to simulate a post filter */ |
851 | int dump, /* true to dump sample to dump file */ | 431 | int pf, /* true to enable actual LPC post filter */ |
852 | int sim_pf, /* true to simulate a post filter */ | 432 | int bass_boost, /* enable LPC filter 0-1kHz 3dB boost */ |
853 | int pf, /* true to enable actual LPC post filter */ | 433 | float beta, float gamma, /* LPC post filter parameters */ |
854 | int bass_boost, /* enable LPC filter 0-1kHz 3dB boost */ | 434 | COMP Aw[] /* output power spectrum */ |
855 | float beta, | 435 | ) { |
856 | float gamma, /* LPC post filter parameters */ | 436 | int i, m; /* loop variables */ |
857 | COMP Aw[] /* output power spectrum */ | 437 | int am, bm; /* limits of current band */ |
858 | ) | 438 | float r; /* no. rads/bin */ |
859 | { | 439 | float Em; /* energy in band */ |
860 | int i,m; /* loop variables */ | 440 | float Am; /* spectral amplitude sample */ |
861 | int am,bm; /* limits of current band */ | ||
862 | float r; /* no. rads/bin */ | ||
863 | float Em; /* energy in band */ | ||
864 | float Am; /* spectral amplitude sample */ | ||
865 | float signal, noise; | 441 | float signal, noise; |
866 | PROFILE_VAR(tstart, tfft, tpw, tpf); | 442 | PROFILE_VAR(tstart, tfft, tpw, tpf); |
867 | 443 | ||
868 | PROFILE_SAMPLE(tstart); | 444 | PROFILE_SAMPLE(tstart); |
869 | 445 | ||
870 | r = TWO_PI/(FFT_ENC); | 446 | r = TWO_PI / (FFT_ENC); |
871 | 447 | ||
872 | /* Determine DFT of A(exp(jw)) --------------------------------------------*/ | 448 | /* Determine DFT of A(exp(jw)) --------------------------------------------*/ |
873 | { | 449 | { |
874 | float a[FFT_ENC]; /* input to FFT for power spectrum */ | 450 | float a[FFT_ENC]; /* input to FFT for power spectrum */ |
875 | 451 | ||
876 | for(i=0; i<FFT_ENC; i++) { | 452 | for (i = 0; i < FFT_ENC; i++) { |
877 | a[i] = 0.0; | 453 | a[i] = 0.0; |
878 | } | 454 | } |
879 | 455 | ||
880 | for(i=0; i<=order; i++) | 456 | for (i = 0; i <= order; i++) a[i] = ak[i]; |
881 | a[i] = ak[i]; | 457 | codec2_fftr(fftr_fwd_cfg, a, Aw); |
882 | codec2_fftr(fftr_fwd_cfg, a, Aw); | ||
883 | } | 458 | } |
884 | PROFILE_SAMPLE_AND_LOG(tfft, tstart, " fft"); | 459 | PROFILE_SAMPLE_AND_LOG(tfft, tstart, " fft"); |
885 | 460 | ||
886 | /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/ | 461 | /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/ |
887 | 462 | ||
888 | float Pw[FFT_ENC/2]; | 463 | float Pw[FFT_ENC / 2]; |
889 | 464 | ||
890 | #ifndef FDV_ARM_MATH | 465 | #ifndef FDV_ARM_MATH |
891 | for(i=0; i<FFT_ENC/2; i++) { | 466 | for (i = 0; i < FFT_ENC / 2; i++) { |
892 | Pw[i] = 1.0/(Aw[i].real*Aw[i].real + Aw[i].imag*Aw[i].imag + 1E-6); | 467 | Pw[i] = 1.0 / (Aw[i].real * Aw[i].real + Aw[i].imag * Aw[i].imag + 1E-6); |
893 | } | 468 | } |
894 | #else | 469 | #else |
895 | // this difference may seem strange, but the gcc for STM32F4 generates almost 5 times | 470 | // this difference may seem strange, but the gcc for STM32F4 generates almost |
896 | // faster code with the two loops: 1120 ms -> 242 ms | 471 | // 5 times faster code with the two loops: 1120 ms -> 242 ms so please leave |
897 | // so please leave it as is or improve further | 472 | // it as is or improve further since this code is called 4 times it results in |
898 | // since this code is called 4 times it results in almost 4ms gain (21ms -> 17ms per audio frame decode @ 1300 ) | 473 | // almost 4ms gain (21ms -> 17ms per audio frame decode @ 1300 ) |
899 | 474 | ||
900 | for(i=0; i<FFT_ENC/2; i++) | 475 | for (i = 0; i < FFT_ENC / 2; i++) { |
901 | { | 476 | Pw[i] = Aw[i].real * Aw[i].real + Aw[i].imag * Aw[i].imag + 1E-6; |
902 | Pw[i] = Aw[i].real * Aw[i].real + Aw[i].imag * Aw[i].imag + 1E-6; | ||
903 | } | 477 | } |
904 | for(i=0; i<FFT_ENC/2; i++) { | 478 | for (i = 0; i < FFT_ENC / 2; i++) { |
905 | Pw[i] = 1.0/(Pw[i]); | 479 | Pw[i] = 1.0 / (Pw[i]); |
906 | } | 480 | } |
907 | #endif | 481 | #endif |
908 | 482 | ||
909 | PROFILE_SAMPLE_AND_LOG(tpw, tfft, " Pw"); | 483 | PROFILE_SAMPLE_AND_LOG(tpw, tfft, " Pw"); |
910 | 484 | ||
911 | if (pf) | 485 | if (pf) |
912 | lpc_post_filter(fftr_fwd_cfg, Pw, ak, order, dump, beta, gamma, bass_boost, E); | 486 | lpc_post_filter(fftr_fwd_cfg, Pw, ak, order, dump, beta, gamma, bass_boost, |
487 | E); | ||
913 | else { | 488 | else { |
914 | for(i=0; i<FFT_ENC/2; i++) { | 489 | for (i = 0; i < FFT_ENC / 2; i++) { |
915 | Pw[i] *= E; | 490 | Pw[i] *= E; |
916 | } | 491 | } |
917 | } | 492 | } |
918 | 493 | ||
919 | PROFILE_SAMPLE_AND_LOG(tpf, tpw, " LPC post filter"); | 494 | PROFILE_SAMPLE_AND_LOG(tpf, tpw, " LPC post filter"); |
920 | 495 | ||
921 | #ifdef DUMP | 496 | #ifdef DUMP |
922 | if (dump) | 497 | if (dump) dump_Pw(Pw); |
923 | dump_Pw(Pw); | 498 | #endif |
924 | #endif | ||
925 | 499 | ||
926 | /* Determine magnitudes from P(w) ----------------------------------------*/ | 500 | /* Determine magnitudes from P(w) ----------------------------------------*/ |
927 | 501 | ||
928 | /* when used just by decoder {A} might be all zeroes so init signal | 502 | /* when used just by decoder {A} might be all zeroes so init signal |
929 | and noise to prevent log(0) errors */ | 503 | and noise to prevent log(0) errors */ |
930 | 504 | ||
931 | signal = 1E-30; noise = 1E-32; | 505 | signal = 1E-30; |
932 | 506 | noise = 1E-32; | |
933 | for(m=1; m<=model->L; m++) { | 507 | |
934 | am = (int)((m - 0.5)*model->Wo/r + 0.5); | 508 | for (m = 1; m <= model->L; m++) { |
935 | bm = (int)((m + 0.5)*model->Wo/r + 0.5); | 509 | am = (int)((m - 0.5) * model->Wo / r + 0.5); |
936 | 510 | bm = (int)((m + 0.5) * model->Wo / r + 0.5); | |
937 | // FIXME: With arm_rfft_fast_f32 we have to use this | 511 | |
938 | // otherwise sometimes a to high bm is calculated | 512 | // FIXME: With arm_rfft_fast_f32 we have to use this |
939 | // which causes trouble later in the calculation | 513 | // otherwise sometimes a to high bm is calculated |
940 | // chain | 514 | // which causes trouble later in the calculation |
941 | // it seems for some reason model->Wo is calculated somewhat too high | 515 | // chain |
942 | if (bm>FFT_ENC/2) | 516 | // it seems for some reason model->Wo is calculated somewhat too high |
943 | { | 517 | if (bm > FFT_ENC / 2) { |
944 | bm = FFT_ENC/2; | 518 | bm = FFT_ENC / 2; |
945 | } | 519 | } |
946 | Em = 0.0; | 520 | Em = 0.0; |
947 | 521 | ||
948 | for(i=am; i<bm; i++) | 522 | for (i = am; i < bm; i++) Em += Pw[i]; |
949 | Em += Pw[i]; | 523 | Am = sqrtf(Em); |
950 | Am = sqrtf(Em); | 524 | |
951 | 525 | signal += model->A[m] * model->A[m]; | |
952 | signal += model->A[m]*model->A[m]; | 526 | noise += (model->A[m] - Am) * (model->A[m] - Am); |
953 | noise += (model->A[m] - Am)*(model->A[m] - Am); | 527 | |
954 | 528 | /* This code significantly improves perf of LPC model, in | |
955 | /* This code significantly improves perf of LPC model, in | 529 | particular when combined with phase0. The LPC spectrum tends |
956 | particular when combined with phase0. The LPC spectrum tends | 530 | to track just under the peaks of the spectral envelope, and |
957 | to track just under the peaks of the spectral envelope, and | 531 | just above nulls. This algorithm does the reverse to |
958 | just above nulls. This algorithm does the reverse to | 532 | compensate - raising the amplitudes of spectral peaks, while |
959 | compensate - raising the amplitudes of spectral peaks, while | 533 | attenuating the null. This enhances the formants, and |
960 | attenuating the null. This enhances the formants, and | 534 | suppresses the energy between formants. */ |
961 | supresses the energy between formants. */ | 535 | |
962 | 536 | if (sim_pf) { | |
963 | if (sim_pf) { | 537 | if (Am > model->A[m]) Am *= 0.7; |
964 | if (Am > model->A[m]) | 538 | if (Am < model->A[m]) Am *= 1.4; |
965 | Am *= 0.7; | 539 | } |
966 | if (Am < model->A[m]) | 540 | model->A[m] = Am; |
967 | Am *= 1.4; | ||
968 | } | ||
969 | model->A[m] = Am; | ||
970 | } | 541 | } |
971 | *snr = 10.0*log10f(signal/noise); | 542 | *snr = 10.0 * log10f(signal / noise); |
972 | 543 | ||
973 | PROFILE_SAMPLE_AND_LOG2(tpf, " rec"); | 544 | PROFILE_SAMPLE_AND_LOG2(tpf, " rec"); |
974 | } | 545 | } |
@@ -983,19 +554,18 @@ void aks_to_M2( | |||
983 | 554 | ||
984 | \*---------------------------------------------------------------------------*/ | 555 | \*---------------------------------------------------------------------------*/ |
985 | 556 | ||
986 | int encode_Wo(C2CONST *c2const, float Wo, int bits) | 557 | int encode_Wo(C2CONST *c2const, float Wo, int bits) { |
987 | { | 558 | int index, Wo_levels = 1 << bits; |
988 | int index, Wo_levels = 1<<bits; | 559 | float Wo_min = c2const->Wo_min; |
989 | float Wo_min = c2const->Wo_min; | 560 | float Wo_max = c2const->Wo_max; |
990 | float Wo_max = c2const->Wo_max; | 561 | float norm; |
991 | float norm; | ||
992 | 562 | ||
993 | norm = (Wo - Wo_min)/(Wo_max - Wo_min); | 563 | norm = (Wo - Wo_min) / (Wo_max - Wo_min); |
994 | index = floorf(Wo_levels * norm + 0.5); | 564 | index = floorf(Wo_levels * norm + 0.5); |
995 | if (index < 0 ) index = 0; | 565 | if (index < 0) index = 0; |
996 | if (index > (Wo_levels-1)) index = Wo_levels-1; | 566 | if (index > (Wo_levels - 1)) index = Wo_levels - 1; |
997 | 567 | ||
998 | return index; | 568 | return index; |
999 | } | 569 | } |
1000 | 570 | ||
1001 | /*---------------------------------------------------------------------------*\ | 571 | /*---------------------------------------------------------------------------*\ |
@@ -1008,18 +578,17 @@ int encode_Wo(C2CONST *c2const, float Wo, int bits) | |||
1008 | 578 | ||
1009 | \*---------------------------------------------------------------------------*/ | 579 | \*---------------------------------------------------------------------------*/ |
1010 | 580 | ||
1011 | float decode_Wo(C2CONST *c2const, int index, int bits) | 581 | float decode_Wo(C2CONST *c2const, int index, int bits) { |
1012 | { | 582 | float Wo_min = c2const->Wo_min; |
1013 | float Wo_min = c2const->Wo_min; | 583 | float Wo_max = c2const->Wo_max; |
1014 | float Wo_max = c2const->Wo_max; | 584 | float step; |
1015 | float step; | 585 | float Wo; |
1016 | float Wo; | 586 | int Wo_levels = 1 << bits; |
1017 | int Wo_levels = 1<<bits; | ||
1018 | 587 | ||
1019 | step = (Wo_max - Wo_min)/Wo_levels; | 588 | step = (Wo_max - Wo_min) / Wo_levels; |
1020 | Wo = Wo_min + step*(index); | 589 | Wo = Wo_min + step * (index); |
1021 | 590 | ||
1022 | return Wo; | 591 | return Wo; |
1023 | } | 592 | } |
1024 | 593 | ||
1025 | /*---------------------------------------------------------------------------*\ | 594 | /*---------------------------------------------------------------------------*\ |
@@ -1032,19 +601,18 @@ float decode_Wo(C2CONST *c2const, int index, int bits) | |||
1032 | 601 | ||
1033 | \*---------------------------------------------------------------------------*/ | 602 | \*---------------------------------------------------------------------------*/ |
1034 | 603 | ||
1035 | int encode_log_Wo(C2CONST *c2const, float Wo, int bits) | 604 | int encode_log_Wo(C2CONST *c2const, float Wo, int bits) { |
1036 | { | 605 | int index, Wo_levels = 1 << bits; |
1037 | int index, Wo_levels = 1<<bits; | 606 | float Wo_min = c2const->Wo_min; |
1038 | float Wo_min = c2const->Wo_min; | 607 | float Wo_max = c2const->Wo_max; |
1039 | float Wo_max = c2const->Wo_max; | 608 | float norm; |
1040 | float norm; | ||
1041 | 609 | ||
1042 | norm = (log10f(Wo) - log10f(Wo_min))/(log10f(Wo_max) - log10f(Wo_min)); | 610 | norm = (log10f(Wo) - log10f(Wo_min)) / (log10f(Wo_max) - log10f(Wo_min)); |
1043 | index = floorf(Wo_levels * norm + 0.5); | 611 | index = floorf(Wo_levels * norm + 0.5); |
1044 | if (index < 0 ) index = 0; | 612 | if (index < 0) index = 0; |
1045 | if (index > (Wo_levels-1)) index = Wo_levels-1; | 613 | if (index > (Wo_levels - 1)) index = Wo_levels - 1; |
1046 | 614 | ||
1047 | return index; | 615 | return index; |
1048 | } | 616 | } |
1049 | 617 | ||
1050 | /*---------------------------------------------------------------------------*\ | 618 | /*---------------------------------------------------------------------------*\ |
@@ -1057,99 +625,18 @@ int encode_log_Wo(C2CONST *c2const, float Wo, int bits) | |||
1057 | 625 | ||
1058 | \*---------------------------------------------------------------------------*/ | 626 | \*---------------------------------------------------------------------------*/ |
1059 | 627 | ||
1060 | float decode_log_Wo(C2CONST *c2const, int index, int bits) | 628 | float decode_log_Wo(C2CONST *c2const, int index, int bits) { |
1061 | { | 629 | float Wo_min = c2const->Wo_min; |
1062 | float Wo_min = c2const->Wo_min; | 630 | float Wo_max = c2const->Wo_max; |
1063 | float Wo_max = c2const->Wo_max; | 631 | float step; |
1064 | float step; | 632 | float Wo; |
1065 | float Wo; | 633 | int Wo_levels = 1 << bits; |
1066 | int Wo_levels = 1<<bits; | ||
1067 | |||
1068 | step = (log10f(Wo_max) - log10f(Wo_min))/Wo_levels; | ||
1069 | Wo = log10f(Wo_min) + step*(index); | ||
1070 | |||
1071 | return POW10F(Wo); | ||
1072 | } | ||
1073 | |||
1074 | #if 0 | ||
1075 | /*---------------------------------------------------------------------------*\ | ||
1076 | |||
1077 | FUNCTION....: encode_Wo_dt() | ||
1078 | AUTHOR......: David Rowe | ||
1079 | DATE CREATED: 6 Nov 2011 | ||
1080 | |||
1081 | Encodes Wo difference from last frame. | ||
1082 | |||
1083 | \*---------------------------------------------------------------------------*/ | ||
1084 | |||
1085 | int encode_Wo_dt(C2CONST *c2const, float Wo, float prev_Wo) | ||
1086 | { | ||
1087 | int index, mask, max_index, min_index; | ||
1088 | float Wo_min = c2const->Wo_min; | ||
1089 | float Wo_max = c2const->Wo_max; | ||
1090 | float norm; | ||
1091 | |||
1092 | norm = (Wo - prev_Wo)/(Wo_max - Wo_min); | ||
1093 | index = floorf(WO_LEVELS * norm + 0.5); | ||
1094 | //printf("ENC index: %d ", index); | ||
1095 | |||
1096 | /* hard limit */ | ||
1097 | |||
1098 | max_index = (1 << (WO_DT_BITS-1)) - 1; | ||
1099 | min_index = - (max_index+1); | ||
1100 | if (index > max_index) index = max_index; | ||
1101 | if (index < min_index) index = min_index; | ||
1102 | //printf("max_index: %d min_index: %d hard index: %d ", | ||
1103 | // max_index, min_index, index); | ||
1104 | |||
1105 | /* mask so that only LSB WO_DT_BITS remain, bit WO_DT_BITS is the sign bit */ | ||
1106 | |||
1107 | mask = ((1 << WO_DT_BITS) - 1); | ||
1108 | index &= mask; | ||
1109 | //printf("mask: 0x%x index: 0x%x\n", mask, index); | ||
1110 | |||
1111 | return index; | ||
1112 | } | ||
1113 | |||
1114 | /*---------------------------------------------------------------------------*\ | ||
1115 | |||
1116 | FUNCTION....: decode_Wo_dt() | ||
1117 | AUTHOR......: David Rowe | ||
1118 | DATE CREATED: 6 Nov 2011 | ||
1119 | |||
1120 | Decodes Wo using WO_DT_BITS difference from last frame. | ||
1121 | |||
1122 | \*---------------------------------------------------------------------------*/ | ||
1123 | |||
1124 | float decode_Wo_dt(C2CONST *c2const, int index, float prev_Wo) | ||
1125 | { | ||
1126 | float Wo_min = c2const->Wo_min; | ||
1127 | float Wo_max = c2const->Wo_max; | ||
1128 | float step; | ||
1129 | float Wo; | ||
1130 | int mask; | ||
1131 | |||
1132 | /* sign extend index */ | ||
1133 | |||
1134 | //printf("DEC index: %d "); | ||
1135 | if (index & (1 << (WO_DT_BITS-1))) { | ||
1136 | mask = ~((1 << WO_DT_BITS) - 1); | ||
1137 | index |= mask; | ||
1138 | } | ||
1139 | //printf("DEC mask: 0x%x index: %d \n", mask, index); | ||
1140 | |||
1141 | step = (Wo_max - Wo_min)/WO_LEVELS; | ||
1142 | Wo = prev_Wo + step*(index); | ||
1143 | |||
1144 | /* bit errors can make us go out of range leading to all sorts of | ||
1145 | probs like seg faults */ | ||
1146 | 634 | ||
1147 | if (Wo > Wo_max) Wo = Wo_max; | 635 | step = (log10f(Wo_max) - log10f(Wo_min)) / Wo_levels; |
1148 | if (Wo < Wo_min) Wo = Wo_min; | 636 | Wo = log10f(Wo_min) + step * (index); |
1149 | 637 | ||
1150 | return Wo; | 638 | return POW10F(Wo); |
1151 | } | 639 | } |
1152 | #endif | ||
1153 | 640 | ||
1154 | /*---------------------------------------------------------------------------*\ | 641 | /*---------------------------------------------------------------------------*\ |
1155 | 642 | ||
@@ -1163,56 +650,46 @@ float decode_Wo_dt(C2CONST *c2const, int index, float prev_Wo) | |||
1163 | 650 | ||
1164 | \*---------------------------------------------------------------------------*/ | 651 | \*---------------------------------------------------------------------------*/ |
1165 | 652 | ||
1166 | float speech_to_uq_lsps(float lsp[], | 653 | float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], |
1167 | float ak[], | 654 | int m_pitch, int order) { |
1168 | float Sn[], | 655 | int i, roots; |
1169 | float w[], | 656 | float Wn[m_pitch]; |
1170 | int m_pitch, | 657 | float R[order + 1]; |
1171 | int order | 658 | float e, E; |
1172 | ) | 659 | |
1173 | { | 660 | e = 0.0; |
1174 | int i, roots; | 661 | for (i = 0; i < m_pitch; i++) { |
1175 | float Wn[m_pitch]; | 662 | Wn[i] = Sn[i] * w[i]; |
1176 | float R[order+1]; | 663 | e += Wn[i] * Wn[i]; |
1177 | float e, E; | 664 | } |
1178 | |||
1179 | e = 0.0; | ||
1180 | for(i=0; i<m_pitch; i++) { | ||
1181 | Wn[i] = Sn[i]*w[i]; | ||
1182 | e += Wn[i]*Wn[i]; | ||
1183 | } | ||
1184 | 665 | ||
1185 | /* trap 0 energy case as LPC analysis will fail */ | 666 | /* trap 0 energy case as LPC analysis will fail */ |
1186 | 667 | ||
1187 | if (e == 0.0) { | 668 | if (e == 0.0) { |
1188 | for(i=0; i<order; i++) | 669 | for (i = 0; i < order; i++) lsp[i] = (PI / order) * (float)i; |
1189 | lsp[i] = (PI/order)*(float)i; | 670 | return 0.0; |
1190 | return 0.0; | 671 | } |
1191 | } | ||
1192 | 672 | ||
1193 | autocorrelate(Wn, R, m_pitch, order); | 673 | autocorrelate(Wn, R, m_pitch, order); |
1194 | levinson_durbin(R, ak, order); | 674 | levinson_durbin(R, ak, order); |
1195 | 675 | ||
1196 | E = 0.0; | 676 | E = 0.0; |
1197 | for(i=0; i<=order; i++) | 677 | for (i = 0; i <= order; i++) E += ak[i] * R[i]; |
1198 | E += ak[i]*R[i]; | ||
1199 | 678 | ||
1200 | /* 15 Hz BW expansion as I can't hear the difference and it may help | 679 | /* 15 Hz BW expansion as I can't hear the difference and it may help |
1201 | help occasional fails in the LSP root finding. Important to do this | 680 | help occasional fails in the LSP root finding. Important to do this |
1202 | after energy calculation to avoid -ve energy values. | 681 | after energy calculation to avoid -ve energy values. |
1203 | */ | 682 | */ |
1204 | 683 | ||
1205 | for(i=0; i<=order; i++) | 684 | for (i = 0; i <= order; i++) ak[i] *= powf(0.994, (float)i); |
1206 | ak[i] *= powf(0.994,(float)i); | ||
1207 | 685 | ||
1208 | roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); | 686 | roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); |
1209 | if (roots != order) { | 687 | if (roots != order) { |
1210 | /* if root finding fails use some benign LSP values instead */ | 688 | /* if root finding fails use some benign LSP values instead */ |
1211 | for(i=0; i<order; i++) | 689 | for (i = 0; i < order; i++) lsp[i] = (PI / order) * (float)i; |
1212 | lsp[i] = (PI/order)*(float)i; | 690 | } |
1213 | } | ||
1214 | 691 | ||
1215 | return E; | 692 | return E; |
1216 | } | 693 | } |
1217 | 694 | ||
1218 | /*---------------------------------------------------------------------------*\ | 695 | /*---------------------------------------------------------------------------*\ |
@@ -1221,317 +698,60 @@ float speech_to_uq_lsps(float lsp[], | |||
1221 | AUTHOR......: David Rowe | 698 | AUTHOR......: David Rowe |
1222 | DATE CREATED: 22/8/2010 | 699 | DATE CREATED: 22/8/2010 |
1223 | 700 | ||
1224 | Thirty-six bit sclar LSP quantiser. From a vector of unquantised | 701 | Scalar LSP quantiser. From a vector of unquantised (floating point) |
1225 | (floating point) LSPs finds the quantised LSP indexes. | 702 | LSPs finds the quantised LSP indexes. |
1226 | |||
1227 | \*---------------------------------------------------------------------------*/ | ||
1228 | |||
1229 | void encode_lsps_scalar(int indexes[], float lsp[], int order) | ||
1230 | { | ||
1231 | int i,k,m; | ||
1232 | float wt[1]; | ||
1233 | float lsp_hz[order]; | ||
1234 | const float * cb; | ||
1235 | float se; | ||
1236 | |||
1237 | /* convert from radians to Hz so we can use human readable | ||
1238 | frequencies */ | ||
1239 | |||
1240 | for(i=0; i<order; i++) | ||
1241 | lsp_hz[i] = (4000.0/PI)*lsp[i]; | ||
1242 | |||
1243 | /* scalar quantisers */ | ||
1244 | |||
1245 | wt[0] = 1.0; | ||
1246 | for(i=0; i<order; i++) { | ||
1247 | k = lsp_cb[i].k; | ||
1248 | m = lsp_cb[i].m; | ||
1249 | cb = lsp_cb[i].cb; | ||
1250 | indexes[i] = quantise(cb, &lsp_hz[i], wt, k, m, &se); | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | /*---------------------------------------------------------------------------*\ | ||
1255 | |||
1256 | FUNCTION....: decode_lsps_scalar() | ||
1257 | AUTHOR......: David Rowe | ||
1258 | DATE CREATED: 22/8/2010 | ||
1259 | |||
1260 | From a vector of quantised LSP indexes, returns the quantised | ||
1261 | (floating point) LSPs. | ||
1262 | |||
1263 | \*---------------------------------------------------------------------------*/ | ||
1264 | |||
1265 | void decode_lsps_scalar(float lsp[], int indexes[], int order) | ||
1266 | { | ||
1267 | int i,k; | ||
1268 | float lsp_hz[order]; | ||
1269 | const float * cb; | ||
1270 | |||
1271 | for(i=0; i<order; i++) { | ||
1272 | k = lsp_cb[i].k; | ||
1273 | cb = lsp_cb[i].cb; | ||
1274 | lsp_hz[i] = cb[indexes[i]*k]; | ||
1275 | } | ||
1276 | |||
1277 | /* convert back to radians */ | ||
1278 | |||
1279 | for(i=0; i<order; i++) | ||
1280 | lsp[i] = (PI/4000.0)*lsp_hz[i]; | ||
1281 | } | ||
1282 | |||
1283 | |||
1284 | /*---------------------------------------------------------------------------*\ | ||
1285 | |||
1286 | FUNCTION....: encode_mels_scalar() | ||
1287 | AUTHOR......: David Rowe | ||
1288 | DATE CREATED: April 2015 | ||
1289 | |||
1290 | Low bit rate mel coeff encoder. | ||
1291 | 703 | ||
1292 | \*---------------------------------------------------------------------------*/ | 704 | \*---------------------------------------------------------------------------*/ |
1293 | 705 | ||
1294 | void encode_mels_scalar(int indexes[], float mels[], int order) | 706 | void encode_lsps_scalar(int indexes[], float lsp[], int order) { |
1295 | { | 707 | int i, k, m; |
1296 | int i,m; | 708 | float wt[1]; |
1297 | float wt[1]; | 709 | float lsp_hz[order]; |
1298 | const float * cb; | 710 | const float *cb; |
1299 | float se, mel_, dmel; | 711 | float se; |
1300 | |||
1301 | /* scalar quantisers */ | ||
1302 | |||
1303 | wt[0] = 1.0; | ||
1304 | for(i=0; i<order; i++) { | ||
1305 | m = mel_cb[i].m; | ||
1306 | cb = mel_cb[i].cb; | ||
1307 | if (i%2) { | ||
1308 | /* on odd mels quantise difference */ | ||
1309 | mel_ = mel_cb[i-1].cb[indexes[i-1]]; | ||
1310 | dmel = mels[i] - mel_; | ||
1311 | indexes[i] = quantise(cb, &dmel, wt, 1, m, &se); | ||
1312 | //printf("%d mel: %f mel_: %f dmel: %f index: %d\n", i, mels[i], mel_, dmel, indexes[i]); | ||
1313 | } | ||
1314 | else { | ||
1315 | indexes[i] = quantise(cb, &mels[i], wt, 1, m, &se); | ||
1316 | //printf("%d mel: %f dmel: %f index: %d\n", i, mels[i], 0.0, indexes[i]); | ||
1317 | } | ||
1318 | 712 | ||
1319 | } | 713 | /* convert from radians to Hz so we can use human readable |
1320 | } | 714 | frequencies */ |
1321 | 715 | ||
716 | for (i = 0; i < order; i++) lsp_hz[i] = (4000.0 / PI) * lsp[i]; | ||
1322 | 717 | ||
1323 | /*---------------------------------------------------------------------------*\ | 718 | /* scalar quantisers */ |
1324 | 719 | ||
1325 | FUNCTION....: decode_mels_scalar() | 720 | wt[0] = 1.0; |
1326 | AUTHOR......: David Rowe | 721 | for (i = 0; i < order; i++) { |
1327 | DATE CREATED: April 2015 | 722 | k = lsp_cb[i].k; |
1328 | 723 | m = lsp_cb[i].m; | |
1329 | From a vector of quantised mel indexes, returns the quantised | 724 | cb = lsp_cb[i].cb; |
1330 | (floating point) mels. | 725 | indexes[i] = quantise(cb, &lsp_hz[i], wt, k, m, &se); |
1331 | 726 | } | |
1332 | \*---------------------------------------------------------------------------*/ | ||
1333 | |||
1334 | void decode_mels_scalar(float mels[], int indexes[], int order) | ||
1335 | { | ||
1336 | int i; | ||
1337 | const float * cb; | ||
1338 | |||
1339 | for(i=0; i<order; i++) { | ||
1340 | cb = mel_cb[i].cb; | ||
1341 | if (i%2) { | ||
1342 | /* on odd mels quantise difference */ | ||
1343 | mels[i] = mels[i-1] + cb[indexes[i]]; | ||
1344 | } | ||
1345 | else | ||
1346 | mels[i] = cb[indexes[i]]; | ||
1347 | } | ||
1348 | |||
1349 | } | ||
1350 | |||
1351 | |||
1352 | #ifdef __EXPERIMENTAL__ | ||
1353 | |||
1354 | /*---------------------------------------------------------------------------*\ | ||
1355 | |||
1356 | FUNCTION....: encode_lsps_diff_freq_vq() | ||
1357 | AUTHOR......: David Rowe | ||
1358 | DATE CREATED: 15 November 2011 | ||
1359 | |||
1360 | Twenty-five bit LSP quantiser. LSPs 1-4 are quantised with scalar | ||
1361 | LSP differences (in frequency, i.e difference from the previous | ||
1362 | LSP). LSPs 5-10 are quantised with a VQ trained generated using | ||
1363 | vqtrainjnd.c | ||
1364 | |||
1365 | \*---------------------------------------------------------------------------*/ | ||
1366 | |||
1367 | void encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order) | ||
1368 | { | ||
1369 | int i,k,m; | ||
1370 | float lsp_hz[order]; | ||
1371 | float lsp__hz[order]; | ||
1372 | float dlsp[order]; | ||
1373 | float dlsp_[order]; | ||
1374 | float wt[order]; | ||
1375 | const float * cb; | ||
1376 | float se; | ||
1377 | |||
1378 | for(i=0; i<order; i++) { | ||
1379 | wt[i] = 1.0; | ||
1380 | } | ||
1381 | |||
1382 | /* convert from radians to Hz so we can use human readable | ||
1383 | frequencies */ | ||
1384 | |||
1385 | for(i=0; i<order; i++) | ||
1386 | lsp_hz[i] = (4000.0/PI)*lsp[i]; | ||
1387 | |||
1388 | /* scalar quantisers for LSP differences 1..4 */ | ||
1389 | |||
1390 | wt[0] = 1.0; | ||
1391 | for(i=0; i<4; i++) { | ||
1392 | if (i) | ||
1393 | dlsp[i] = lsp_hz[i] - lsp__hz[i-1]; | ||
1394 | else | ||
1395 | dlsp[0] = lsp_hz[0]; | ||
1396 | |||
1397 | k = lsp_cbd[i].k; | ||
1398 | m = lsp_cbd[i].m; | ||
1399 | cb = lsp_cbd[i].cb; | ||
1400 | indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se); | ||
1401 | dlsp_[i] = cb[indexes[i]*k]; | ||
1402 | |||
1403 | if (i) | ||
1404 | lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; | ||
1405 | else | ||
1406 | lsp__hz[0] = dlsp_[0]; | ||
1407 | } | ||
1408 | |||
1409 | /* VQ LSPs 5,6,7,8,9,10 */ | ||
1410 | |||
1411 | k = lsp_cbjnd[4].k; | ||
1412 | m = lsp_cbjnd[4].m; | ||
1413 | cb = lsp_cbjnd[4].cb; | ||
1414 | indexes[4] = quantise(cb, &lsp_hz[4], &wt[4], k, m, &se); | ||
1415 | } | 727 | } |
1416 | 728 | ||
1417 | |||
1418 | /*---------------------------------------------------------------------------*\ | 729 | /*---------------------------------------------------------------------------*\ |
1419 | 730 | ||
1420 | FUNCTION....: decode_lsps_diff_freq_vq() | 731 | FUNCTION....: decode_lsps_scalar() |
1421 | AUTHOR......: David Rowe | 732 | AUTHOR......: David Rowe |
1422 | DATE CREATED: 15 Nov 2011 | 733 | DATE CREATED: 22/8/2010 |
1423 | 734 | ||
1424 | From a vector of quantised LSP indexes, returns the quantised | 735 | From a vector of quantised LSP indexes, returns the quantised |
1425 | (floating point) LSPs. | 736 | (floating point) LSPs. |
1426 | 737 | ||
1427 | \*---------------------------------------------------------------------------*/ | 738 | \*---------------------------------------------------------------------------*/ |
1428 | 739 | ||
1429 | void decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order) | 740 | void decode_lsps_scalar(float lsp[], int indexes[], int order) { |
1430 | { | 741 | int i, k; |
1431 | int i,k,m; | 742 | float lsp_hz[order]; |
1432 | float dlsp_[order]; | 743 | const float *cb; |
1433 | float lsp__hz[order]; | ||
1434 | const float * cb; | ||
1435 | |||
1436 | /* scalar LSP differences */ | ||
1437 | |||
1438 | for(i=0; i<4; i++) { | ||
1439 | cb = lsp_cbd[i].cb; | ||
1440 | dlsp_[i] = cb[indexes[i]]; | ||
1441 | if (i) | ||
1442 | lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; | ||
1443 | else | ||
1444 | lsp__hz[0] = dlsp_[0]; | ||
1445 | } | ||
1446 | |||
1447 | /* VQ */ | ||
1448 | |||
1449 | k = lsp_cbjnd[4].k; | ||
1450 | m = lsp_cbjnd[4].m; | ||
1451 | cb = lsp_cbjnd[4].cb; | ||
1452 | for(i=4; i<order; i++) | ||
1453 | lsp__hz[i] = cb[indexes[4]*k+i-4]; | ||
1454 | |||
1455 | /* convert back to radians */ | ||
1456 | |||
1457 | for(i=0; i<order; i++) | ||
1458 | lsp_[i] = (PI/4000.0)*lsp__hz[i]; | ||
1459 | } | ||
1460 | |||
1461 | |||
1462 | /*---------------------------------------------------------------------------*\ | ||
1463 | |||
1464 | FUNCTION....: encode_lsps_diff_time() | ||
1465 | AUTHOR......: David Rowe | ||
1466 | DATE CREATED: 12 Sep 2012 | ||
1467 | |||
1468 | Encode difference from preious frames's LSPs using | ||
1469 | 3,3,2,2,2,2,1,1,1,1 scalar quantisers (18 bits total). | ||
1470 | |||
1471 | \*---------------------------------------------------------------------------*/ | ||
1472 | 744 | ||
1473 | void encode_lsps_diff_time(int indexes[], | 745 | for (i = 0; i < order; i++) { |
1474 | float lsps[], | 746 | k = lsp_cb[i].k; |
1475 | float lsps__prev[], | 747 | cb = lsp_cb[i].cb; |
1476 | int order) | 748 | lsp_hz[i] = cb[indexes[i] * k]; |
1477 | { | 749 | } |
1478 | int i,k,m; | ||
1479 | float lsps_dt[order]; | ||
1480 | float wt[LPC_MAX]; | ||
1481 | const float * cb; | ||
1482 | float se; | ||
1483 | |||
1484 | /* Determine difference in time and convert from radians to Hz so | ||
1485 | we can use human readable frequencies */ | ||
1486 | |||
1487 | for(i=0; i<order; i++) { | ||
1488 | lsps_dt[i] = (4000/PI)*(lsps[i] - lsps__prev[i]); | ||
1489 | } | ||
1490 | |||
1491 | /* scalar quantisers */ | ||
1492 | |||
1493 | wt[0] = 1.0; | ||
1494 | for(i=0; i<order; i++) { | ||
1495 | k = lsp_cbdt[i].k; | ||
1496 | m = lsp_cbdt[i].m; | ||
1497 | cb = lsp_cbdt[i].cb; | ||
1498 | indexes[i] = quantise(cb, &lsps_dt[i], wt, k, m, &se); | ||
1499 | } | ||
1500 | |||
1501 | } | ||
1502 | |||
1503 | |||
1504 | /*---------------------------------------------------------------------------*\ | ||
1505 | |||
1506 | FUNCTION....: decode_lsps_diff_time() | ||
1507 | AUTHOR......: David Rowe | ||
1508 | DATE CREATED: 15 Nov 2011 | ||
1509 | |||
1510 | From a quantised LSP indexes, returns the quantised | ||
1511 | (floating point) LSPs. | ||
1512 | |||
1513 | \*---------------------------------------------------------------------------*/ | ||
1514 | |||
1515 | void decode_lsps_diff_time( | ||
1516 | float lsps_[], | ||
1517 | int indexes[], | ||
1518 | float lsps__prev[], | ||
1519 | int order) | ||
1520 | { | ||
1521 | int i,k,m; | ||
1522 | const float * cb; | ||
1523 | |||
1524 | for(i=0; i<order; i++) | ||
1525 | lsps_[i] = lsps__prev[i]; | ||
1526 | 750 | ||
1527 | for(i=0; i<order; i++) { | 751 | /* convert back to radians */ |
1528 | k = lsp_cbdt[i].k; | ||
1529 | cb = lsp_cbdt[i].cb; | ||
1530 | lsps_[i] += (PI/4000.0)*cb[indexes[i]*k]; | ||
1531 | } | ||
1532 | 752 | ||
753 | for (i = 0; i < order; i++) lsp[i] = (PI / 4000.0) * lsp_hz[i]; | ||
1533 | } | 754 | } |
1534 | #endif | ||
1535 | 755 | ||
1536 | /*---------------------------------------------------------------------------*\ | 756 | /*---------------------------------------------------------------------------*\ |
1537 | 757 | ||
@@ -1543,45 +763,40 @@ void decode_lsps_diff_time( | |||
1543 | 763 | ||
1544 | \*---------------------------------------------------------------------------*/ | 764 | \*---------------------------------------------------------------------------*/ |
1545 | 765 | ||
1546 | void encode_lsps_vq(int *indexes, float *x, float *xq, int order) | 766 | void encode_lsps_vq(int *indexes, float *x, float *xq, int order) { |
1547 | { | ||
1548 | int i, n1, n2, n3; | 767 | int i, n1, n2, n3; |
1549 | float err[order], err2[order], err3[order]; | 768 | float err[order], err2[order], err3[order]; |
1550 | float w[order], w2[order], w3[order]; | 769 | float w[order], w2[order], w3[order]; |
1551 | const float *codebook1 = lsp_cbjvm[0].cb; | 770 | const float *codebook1 = lsp_cbjmv[0].cb; |
1552 | const float *codebook2 = lsp_cbjvm[1].cb; | 771 | const float *codebook2 = lsp_cbjmv[1].cb; |
1553 | const float *codebook3 = lsp_cbjvm[2].cb; | 772 | const float *codebook3 = lsp_cbjmv[2].cb; |
1554 | 773 | ||
1555 | w[0] = MIN(x[0], x[1]-x[0]); | 774 | w[0] = MIN(x[0], x[1] - x[0]); |
1556 | for (i=1;i<order-1;i++) | 775 | for (i = 1; i < order - 1; i++) w[i] = MIN(x[i] - x[i - 1], x[i + 1] - x[i]); |
1557 | w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]); | 776 | w[order - 1] = MIN(x[order - 1] - x[order - 2], PI - x[order - 1]); |
1558 | w[order-1] = MIN(x[order-1]-x[order-2], PI-x[order-1]); | ||
1559 | 777 | ||
1560 | compute_weights(x, w, order); | 778 | compute_weights(x, w, order); |
1561 | 779 | ||
1562 | n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, order); | 780 | n1 = find_nearest(codebook1, lsp_cbjmv[0].m, x, order); |
1563 | 781 | ||
1564 | for (i=0;i<order;i++) | 782 | for (i = 0; i < order; i++) { |
1565 | { | 783 | xq[i] = codebook1[order * n1 + i]; |
1566 | xq[i] = codebook1[order*n1+i]; | ||
1567 | err[i] = x[i] - xq[i]; | 784 | err[i] = x[i] - xq[i]; |
1568 | } | 785 | } |
1569 | for (i=0;i<order/2;i++) | 786 | for (i = 0; i < order / 2; i++) { |
1570 | { | 787 | err2[i] = err[2 * i]; |
1571 | err2[i] = err[2*i]; | 788 | err3[i] = err[2 * i + 1]; |
1572 | err3[i] = err[2*i+1]; | 789 | w2[i] = w[2 * i]; |
1573 | w2[i] = w[2*i]; | 790 | w3[i] = w[2 * i + 1]; |
1574 | w3[i] = w[2*i+1]; | ||
1575 | } | 791 | } |
1576 | n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, order/2); | 792 | n2 = find_nearest_weighted(codebook2, lsp_cbjmv[1].m, err2, w2, order / 2); |
1577 | n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, order/2); | 793 | n3 = find_nearest_weighted(codebook3, lsp_cbjmv[2].m, err3, w3, order / 2); |
1578 | 794 | ||
1579 | indexes[0] = n1; | 795 | indexes[0] = n1; |
1580 | indexes[1] = n2; | 796 | indexes[1] = n2; |
1581 | indexes[2] = n3; | 797 | indexes[2] = n3; |
1582 | } | 798 | } |
1583 | 799 | ||
1584 | |||
1585 | /*---------------------------------------------------------------------------*\ | 800 | /*---------------------------------------------------------------------------*\ |
1586 | 801 | ||
1587 | FUNCTION....: decode_lsps_vq() | 802 | FUNCTION....: decode_lsps_vq() |
@@ -1590,31 +805,28 @@ void encode_lsps_vq(int *indexes, float *x, float *xq, int order) | |||
1590 | 805 | ||
1591 | \*---------------------------------------------------------------------------*/ | 806 | \*---------------------------------------------------------------------------*/ |
1592 | 807 | ||
1593 | void decode_lsps_vq(int *indexes, float *xq, int order, int stages) | 808 | void decode_lsps_vq(int *indexes, float *xq, int order, int stages) { |
1594 | { | ||
1595 | int i, n1, n2, n3; | 809 | int i, n1, n2, n3; |
1596 | const float *codebook1 = lsp_cbjvm[0].cb; | 810 | const float *codebook1 = lsp_cbjmv[0].cb; |
1597 | const float *codebook2 = lsp_cbjvm[1].cb; | 811 | const float *codebook2 = lsp_cbjmv[1].cb; |
1598 | const float *codebook3 = lsp_cbjvm[2].cb; | 812 | const float *codebook3 = lsp_cbjmv[2].cb; |
1599 | 813 | ||
1600 | n1 = indexes[0]; | 814 | n1 = indexes[0]; |
1601 | n2 = indexes[1]; | 815 | n2 = indexes[1]; |
1602 | n3 = indexes[2]; | 816 | n3 = indexes[2]; |
1603 | 817 | ||
1604 | for (i=0;i<order;i++) { | 818 | for (i = 0; i < order; i++) { |
1605 | xq[i] = codebook1[order*n1+i]; | 819 | xq[i] = codebook1[order * n1 + i]; |
1606 | } | 820 | } |
1607 | 821 | ||
1608 | if (stages != 1) { | 822 | if (stages != 1) { |
1609 | for (i=0;i<order/2;i++) { | 823 | for (i = 0; i < order / 2; i++) { |
1610 | xq[2*i] += codebook2[order*n2/2+i]; | 824 | xq[2 * i] += codebook2[order * n2 / 2 + i]; |
1611 | xq[2*i+1] += codebook3[order*n3/2+i]; | 825 | xq[2 * i + 1] += codebook3[order * n3 / 2 + i]; |
1612 | } | 826 | } |
1613 | } | 827 | } |
1614 | |||
1615 | } | 828 | } |
1616 | 829 | ||
1617 | |||
1618 | /*---------------------------------------------------------------------------*\ | 830 | /*---------------------------------------------------------------------------*\ |
1619 | 831 | ||
1620 | FUNCTION....: bw_expand_lsps() | 832 | FUNCTION....: bw_expand_lsps() |
@@ -1628,124 +840,45 @@ void decode_lsps_vq(int *indexes, float *xq, int order, int stages) | |||
1628 | 840 | ||
1629 | \*---------------------------------------------------------------------------*/ | 841 | \*---------------------------------------------------------------------------*/ |
1630 | 842 | ||
1631 | void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high) | 843 | void bw_expand_lsps(float lsp[], int order, float min_sep_low, |
1632 | { | 844 | float min_sep_high) { |
1633 | int i; | 845 | int i; |
1634 | |||
1635 | for(i=1; i<4; i++) { | ||
1636 | |||
1637 | if ((lsp[i] - lsp[i-1]) < min_sep_low*(PI/4000.0)) | ||
1638 | lsp[i] = lsp[i-1] + min_sep_low*(PI/4000.0); | ||
1639 | |||
1640 | } | ||
1641 | |||
1642 | /* As quantiser gaps increased, larger BW expansion was required | ||
1643 | to prevent twinkly noises. This may need more experiment for | ||
1644 | different quanstisers. | ||
1645 | */ | ||
1646 | |||
1647 | for(i=4; i<order; i++) { | ||
1648 | if (lsp[i] - lsp[i-1] < min_sep_high*(PI/4000.0)) | ||
1649 | lsp[i] = lsp[i-1] + min_sep_high*(PI/4000.0); | ||
1650 | } | ||
1651 | } | ||
1652 | |||
1653 | void bw_expand_lsps2(float lsp[], | ||
1654 | int order | ||
1655 | ) | ||
1656 | { | ||
1657 | int i; | ||
1658 | |||
1659 | for(i=1; i<4; i++) { | ||
1660 | |||
1661 | if ((lsp[i] - lsp[i-1]) < 100.0*(PI/4000.0)) | ||
1662 | lsp[i] = lsp[i-1] + 100.0*(PI/4000.0); | ||
1663 | 846 | ||
1664 | } | 847 | for (i = 1; i < 4; i++) { |
848 | if ((lsp[i] - lsp[i - 1]) < min_sep_low * (PI / 4000.0)) | ||
849 | lsp[i] = lsp[i - 1] + min_sep_low * (PI / 4000.0); | ||
850 | } | ||
1665 | 851 | ||
1666 | /* As quantiser gaps increased, larger BW expansion was required | 852 | /* As quantiser gaps increased, larger BW expansion was required |
1667 | to prevent twinkly noises. This may need more experiment for | 853 | to prevent twinkly noises. This may need more experiment for |
1668 | different quanstisers. | 854 | different quanstisers. |
1669 | */ | 855 | */ |
1670 | 856 | ||
1671 | for(i=4; i<order; i++) { | 857 | for (i = 4; i < order; i++) { |
1672 | if (lsp[i] - lsp[i-1] < 200.0*(PI/4000.0)) | 858 | if (lsp[i] - lsp[i - 1] < min_sep_high * (PI / 4000.0)) |
1673 | lsp[i] = lsp[i-1] + 200.0*(PI/4000.0); | 859 | lsp[i] = lsp[i - 1] + min_sep_high * (PI / 4000.0); |
1674 | } | 860 | } |
1675 | } | 861 | } |
1676 | 862 | ||
1677 | /*---------------------------------------------------------------------------*\ | 863 | void bw_expand_lsps2(float lsp[], int order) { |
1678 | 864 | int i; | |
1679 | FUNCTION....: locate_lsps_jnd_steps() | ||
1680 | AUTHOR......: David Rowe | ||
1681 | DATE CREATED: 27/10/2011 | ||
1682 | |||
1683 | Applies a form of Bandwidth Expansion (BW) to a vector of LSPs. | ||
1684 | Listening tests have determined that "quantising" the position of | ||
1685 | each LSP to the non-linear steps below introduces a "just noticable | ||
1686 | difference" in the synthesised speech. | ||
1687 | |||
1688 | This operation can be used before quantisation to limit the input | ||
1689 | data to the quantiser to a number of discrete steps. | ||
1690 | |||
1691 | This operation can also be used during quantisation as a form of | ||
1692 | hysteresis in the calculation of quantiser error. For example if | ||
1693 | the quantiser target of lsp1 is 500 Hz, candidate vectors with lsp1 | ||
1694 | of 515 and 495 Hz sound effectively the same. | ||
1695 | |||
1696 | \*---------------------------------------------------------------------------*/ | ||
1697 | |||
1698 | void locate_lsps_jnd_steps(float lsps[], int order) | ||
1699 | { | ||
1700 | int i; | ||
1701 | float lsp_hz, step; | ||
1702 | |||
1703 | assert(order == 10); | ||
1704 | |||
1705 | /* quantise to 25Hz steps */ | ||
1706 | |||
1707 | step = 25; | ||
1708 | for(i=0; i<2; i++) { | ||
1709 | lsp_hz = lsps[i]*4000.0/PI; | ||
1710 | lsp_hz = floorf(lsp_hz/step + 0.5)*step; | ||
1711 | lsps[i] = lsp_hz*PI/4000.0; | ||
1712 | if (i) { | ||
1713 | if (lsps[i] == lsps[i-1]) | ||
1714 | lsps[i] += step*PI/4000.0; | ||
1715 | |||
1716 | } | ||
1717 | } | ||
1718 | |||
1719 | /* quantise to 50Hz steps */ | ||
1720 | |||
1721 | step = 50; | ||
1722 | for(i=2; i<4; i++) { | ||
1723 | lsp_hz = lsps[i]*4000.0/PI; | ||
1724 | lsp_hz = floorf(lsp_hz/step + 0.5)*step; | ||
1725 | lsps[i] = lsp_hz*PI/4000.0; | ||
1726 | if (i) { | ||
1727 | if (lsps[i] == lsps[i-1]) | ||
1728 | lsps[i] += step*PI/4000.0; | ||
1729 | |||
1730 | } | ||
1731 | } | ||
1732 | 865 | ||
1733 | /* quantise to 100Hz steps */ | 866 | for (i = 1; i < 4; i++) { |
867 | if ((lsp[i] - lsp[i - 1]) < 100.0 * (PI / 4000.0)) | ||
868 | lsp[i] = lsp[i - 1] + 100.0 * (PI / 4000.0); | ||
869 | } | ||
1734 | 870 | ||
1735 | step = 100; | 871 | /* As quantiser gaps increased, larger BW expansion was required |
1736 | for(i=4; i<10; i++) { | 872 | to prevent twinkly noises. This may need more experiment for |
1737 | lsp_hz = lsps[i]*4000.0/PI; | 873 | different quanstisers. |
1738 | lsp_hz = floorf(lsp_hz/step + 0.5)*step; | 874 | */ |
1739 | lsps[i] = lsp_hz*PI/4000.0; | ||
1740 | if (i) { | ||
1741 | if (lsps[i] == lsps[i-1]) | ||
1742 | lsps[i] += step*PI/4000.0; | ||
1743 | 875 | ||
1744 | } | 876 | for (i = 4; i < order; i++) { |
1745 | } | 877 | if (lsp[i] - lsp[i - 1] < 200.0 * (PI / 4000.0)) |
878 | lsp[i] = lsp[i - 1] + 200.0 * (PI / 4000.0); | ||
879 | } | ||
1746 | } | 880 | } |
1747 | 881 | ||
1748 | |||
1749 | /*---------------------------------------------------------------------------*\ | 882 | /*---------------------------------------------------------------------------*\ |
1750 | 883 | ||
1751 | FUNCTION....: apply_lpc_correction() | 884 | FUNCTION....: apply_lpc_correction() |
@@ -1757,11 +890,10 @@ void locate_lsps_jnd_steps(float lsps[], int order) | |||
1757 | 890 | ||
1758 | \*---------------------------------------------------------------------------*/ | 891 | \*---------------------------------------------------------------------------*/ |
1759 | 892 | ||
1760 | void apply_lpc_correction(MODEL *model) | 893 | void apply_lpc_correction(MODEL *model) { |
1761 | { | 894 | if (model->Wo < (PI * 150.0 / 4000)) { |
1762 | if (model->Wo < (PI*150.0/4000)) { | 895 | model->A[1] *= 0.032; |
1763 | model->A[1] *= 0.032; | 896 | } |
1764 | } | ||
1765 | } | 897 | } |
1766 | 898 | ||
1767 | /*---------------------------------------------------------------------------*\ | 899 | /*---------------------------------------------------------------------------*\ |
@@ -1774,124 +906,81 @@ void apply_lpc_correction(MODEL *model) | |||
1774 | 906 | ||
1775 | \*---------------------------------------------------------------------------*/ | 907 | \*---------------------------------------------------------------------------*/ |
1776 | 908 | ||
1777 | int encode_energy(float e, int bits) | 909 | int encode_energy(float e, int bits) { |
1778 | { | 910 | int index, e_levels = 1 << bits; |
1779 | int index, e_levels = 1<<bits; | 911 | float e_min = E_MIN_DB; |
1780 | float e_min = E_MIN_DB; | 912 | float e_max = E_MAX_DB; |
1781 | float e_max = E_MAX_DB; | 913 | float norm; |
1782 | float norm; | ||
1783 | |||
1784 | e = 10.0*log10f(e); | ||
1785 | norm = (e - e_min)/(e_max - e_min); | ||
1786 | index = floorf(e_levels * norm + 0.5); | ||
1787 | if (index < 0 ) index = 0; | ||
1788 | if (index > (e_levels-1)) index = e_levels-1; | ||
1789 | |||
1790 | return index; | ||
1791 | } | ||
1792 | |||
1793 | /*---------------------------------------------------------------------------*\ | ||
1794 | |||
1795 | FUNCTION....: decode_energy() | ||
1796 | AUTHOR......: David Rowe | ||
1797 | DATE CREATED: 22/8/2010 | ||
1798 | |||
1799 | Decodes energy using a E_LEVELS quantiser. | ||
1800 | |||
1801 | \*---------------------------------------------------------------------------*/ | ||
1802 | |||
1803 | float decode_energy(int index, int bits) | ||
1804 | { | ||
1805 | float e_min = E_MIN_DB; | ||
1806 | float e_max = E_MAX_DB; | ||
1807 | float step; | ||
1808 | float e; | ||
1809 | int e_levels = 1<<bits; | ||
1810 | 914 | ||
1811 | step = (e_max - e_min)/e_levels; | 915 | e = 10.0 * log10f(e); |
1812 | e = e_min + step*(index); | 916 | norm = (e - e_min) / (e_max - e_min); |
1813 | e = POW10F(e/10.0); | 917 | index = floorf(e_levels * norm + 0.5); |
918 | if (index < 0) index = 0; | ||
919 | if (index > (e_levels - 1)) index = e_levels - 1; | ||
1814 | 920 | ||
1815 | return e; | 921 | return index; |
1816 | } | 922 | } |
1817 | 923 | ||
1818 | #ifdef NOT_USED | ||
1819 | /*---------------------------------------------------------------------------*\ | 924 | /*---------------------------------------------------------------------------*\ |
1820 | 925 | ||
1821 | FUNCTION....: decode_amplitudes() | 926 | FUNCTION....: decode_energy() |
1822 | AUTHOR......: David Rowe | 927 | AUTHOR......: David Rowe |
1823 | DATE CREATED: 22/8/2010 | 928 | DATE CREATED: 22/8/2010 |
1824 | 929 | ||
1825 | Given the amplitude quantiser indexes recovers the harmonic | 930 | Decodes energy using a E_LEVELS quantiser. |
1826 | amplitudes. | ||
1827 | 931 | ||
1828 | \*---------------------------------------------------------------------------*/ | 932 | \*---------------------------------------------------------------------------*/ |
1829 | 933 | ||
1830 | float decode_amplitudes(codec2_fft_cfg fft_fwd_cfg, | 934 | float decode_energy(int index, int bits) { |
1831 | MODEL *model, | 935 | float e_min = E_MIN_DB; |
1832 | float ak[], | 936 | float e_max = E_MAX_DB; |
1833 | int lsp_indexes[], | 937 | float step; |
1834 | int energy_index, | 938 | float e; |
1835 | float lsps[], | 939 | int e_levels = 1 << bits; |
1836 | float *e | ||
1837 | ) | ||
1838 | { | ||
1839 | float snr; | ||
1840 | 940 | ||
1841 | decode_lsps_scalar(lsps, lsp_indexes, LPC_ORD); | 941 | step = (e_max - e_min) / e_levels; |
1842 | bw_expand_lsps(lsps, LPC_ORD); | 942 | e = e_min + step * (index); |
1843 | lsp_to_lpc(lsps, ak, LPC_ORD); | 943 | e = POW10F(e / 10.0); |
1844 | *e = decode_energy(energy_index); | ||
1845 | aks_to_M2(ak, LPC_ORD, model, *e, &snr, 1, 0, 0, 1); | ||
1846 | apply_lpc_correction(model); | ||
1847 | 944 | ||
1848 | return snr; | 945 | return e; |
1849 | } | 946 | } |
1850 | #endif | ||
1851 | 947 | ||
1852 | static float ge_coeff[2] = {0.8, 0.9}; | 948 | static float ge_coeff[2] = {0.8, 0.9}; |
1853 | 949 | ||
1854 | void compute_weights2(const float *x, const float *xp, float *w) | 950 | void compute_weights2(const float *x, const float *xp, float *w) { |
1855 | { | ||
1856 | w[0] = 30; | 951 | w[0] = 30; |
1857 | w[1] = 1; | 952 | w[1] = 1; |
1858 | if (x[1]<0) | 953 | if (x[1] < 0) { |
1859 | { | 954 | w[0] *= .6; |
1860 | w[0] *= .6; | 955 | w[1] *= .3; |
1861 | w[1] *= .3; | ||
1862 | } | 956 | } |
1863 | if (x[1]<-10) | 957 | if (x[1] < -10) { |
1864 | { | 958 | w[0] *= .3; |
1865 | w[0] *= .3; | 959 | w[1] *= .3; |
1866 | w[1] *= .3; | ||
1867 | } | 960 | } |
1868 | /* Higher weight if pitch is stable */ | 961 | /* Higher weight if pitch is stable */ |
1869 | if (fabsf(x[0]-xp[0])<.2) | 962 | if (fabsf(x[0] - xp[0]) < .2) { |
1870 | { | 963 | w[0] *= 2; |
1871 | w[0] *= 2; | 964 | w[1] *= 1.5; |
1872 | w[1] *= 1.5; | 965 | } else if (fabsf(x[0] - xp[0]) > .5) /* Lower if not stable */ |
1873 | } else if (fabsf(x[0]-xp[0])>.5) /* Lower if not stable */ | ||
1874 | { | 966 | { |
1875 | w[0] *= .5; | 967 | w[0] *= .5; |
1876 | } | 968 | } |
1877 | 969 | ||
1878 | /* Lower weight for low energy */ | 970 | /* Lower weight for low energy */ |
1879 | if (x[1] < xp[1]-10) | 971 | if (x[1] < xp[1] - 10) { |
1880 | { | 972 | w[1] *= .5; |
1881 | w[1] *= .5; | ||
1882 | } | 973 | } |
1883 | if (x[1] < xp[1]-20) | 974 | if (x[1] < xp[1] - 20) { |
1884 | { | 975 | w[1] *= .5; |
1885 | w[1] *= .5; | ||
1886 | } | 976 | } |
1887 | 977 | ||
1888 | //w[0] = 30; | 978 | // w[0] = 30; |
1889 | //w[1] = 1; | 979 | // w[1] = 1; |
1890 | 980 | ||
1891 | /* Square the weights because it's applied on the squared error */ | 981 | /* Square the weights because it's applied on the squared error */ |
1892 | w[0] *= w[0]; | 982 | w[0] *= w[0]; |
1893 | w[1] *= w[1]; | 983 | w[1] *= w[1]; |
1894 | |||
1895 | } | 984 | } |
1896 | 985 | ||
1897 | /*---------------------------------------------------------------------------*\ | 986 | /*---------------------------------------------------------------------------*\ |
@@ -1906,7 +995,7 @@ void compute_weights2(const float *x, const float *xp, float *w) | |||
1906 | both the pitch and energy tend to only change by small amounts | 995 | both the pitch and energy tend to only change by small amounts |
1907 | during voiced speech, however it is important that these changes be | 996 | during voiced speech, however it is important that these changes be |
1908 | coded carefully. During unvoiced speech they both change a lot but | 997 | coded carefully. During unvoiced speech they both change a lot but |
1909 | the ear is less sensitve to errors so coarser quantisation is OK. | 998 | the ear is less sensitive to errors so coarser quantisation is OK. |
1910 | 999 | ||
1911 | The ear is sensitive to log energy and loq pitch so we quantise in | 1000 | The ear is sensitive to log energy and loq pitch so we quantise in |
1912 | these domains. That way the error measure used to quantise the | 1001 | these domains. That way the error measure used to quantise the |
@@ -1916,15 +1005,14 @@ void compute_weights2(const float *x, const float *xp, float *w) | |||
1916 | 1005 | ||
1917 | \*---------------------------------------------------------------------------*/ | 1006 | \*---------------------------------------------------------------------------*/ |
1918 | 1007 | ||
1919 | void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]) | 1008 | void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]) { |
1920 | { | 1009 | int i, n1; |
1921 | int i, n1; | 1010 | float x[2]; |
1922 | float x[2]; | 1011 | float err[2]; |
1923 | float err[2]; | 1012 | float w[2]; |
1924 | float w[2]; | ||
1925 | const float *codebook1 = ge_cb[0].cb; | 1013 | const float *codebook1 = ge_cb[0].cb; |
1926 | int nb_entries = ge_cb[0].m; | 1014 | int nb_entries = ge_cb[0].m; |
1927 | int ndim = ge_cb[0].k; | 1015 | int ndim = ge_cb[0].k; |
1928 | float Wo_min = c2const->Wo_min; | 1016 | float Wo_min = c2const->Wo_min; |
1929 | float Wo_max = c2const->Wo_max; | 1017 | float Wo_max = c2const->Wo_max; |
1930 | float Fs = c2const->Fs; | 1018 | float Fs = c2const->Fs; |
@@ -1933,18 +1021,16 @@ void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]) | |||
1933 | 1021 | ||
1934 | assert(Fs == 8000); | 1022 | assert(Fs == 8000); |
1935 | 1023 | ||
1936 | x[0] = log10f((model->Wo/PI)*4000.0/50.0)/log10f(2); | 1024 | x[0] = log10f((model->Wo / PI) * 4000.0 / 50.0) / log10f(2); |
1937 | x[1] = 10.0*log10f(1e-4 + *e); | 1025 | x[1] = 10.0 * log10f(1e-4 + *e); |
1938 | 1026 | ||
1939 | compute_weights2(x, xq, w); | 1027 | compute_weights2(x, xq, w); |
1940 | for (i=0;i<ndim;i++) | 1028 | for (i = 0; i < ndim; i++) err[i] = x[i] - ge_coeff[i] * xq[i]; |
1941 | err[i] = x[i]-ge_coeff[i]*xq[i]; | ||
1942 | n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim); | 1029 | n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim); |
1943 | 1030 | ||
1944 | for (i=0;i<ndim;i++) | 1031 | for (i = 0; i < ndim; i++) { |
1945 | { | 1032 | xq[i] = ge_coeff[i] * xq[i] + codebook1[ndim * n1 + i]; |
1946 | xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i]; | 1033 | err[i] -= codebook1[ndim * n1 + i]; |
1947 | err[i] -= codebook1[ndim*n1+i]; | ||
1948 | } | 1034 | } |
1949 | 1035 | ||
1950 | /* | 1036 | /* |
@@ -1953,7 +1039,7 @@ void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]) | |||
1953 | Wo = (2^x)*(PI*50)/4000; | 1039 | Wo = (2^x)*(PI*50)/4000; |
1954 | */ | 1040 | */ |
1955 | 1041 | ||
1956 | model->Wo = powf(2.0, xq[0])*(PI*50.0)/4000.0; | 1042 | model->Wo = powf(2.0, xq[0]) * (PI * 50.0) / 4000.0; |
1957 | 1043 | ||
1958 | /* bit errors can make us go out of range leading to all sorts of | 1044 | /* bit errors can make us go out of range leading to all sorts of |
1959 | probs like seg faults */ | 1045 | probs like seg faults */ |
@@ -1961,9 +1047,9 @@ void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]) | |||
1961 | if (model->Wo > Wo_max) model->Wo = Wo_max; | 1047 | if (model->Wo > Wo_max) model->Wo = Wo_max; |
1962 | if (model->Wo < Wo_min) model->Wo = Wo_min; | 1048 | if (model->Wo < Wo_min) model->Wo = Wo_min; |
1963 | 1049 | ||
1964 | model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ | 1050 | model->L = PI / model->Wo; /* if we quantise Wo re-compute L */ |
1965 | 1051 | ||
1966 | *e = POW10F(xq[1]/10.0); | 1052 | *e = POW10F(xq[1] / 10.0); |
1967 | } | 1053 | } |
1968 | 1054 | ||
1969 | /*---------------------------------------------------------------------------*\ | 1055 | /*---------------------------------------------------------------------------*\ |
@@ -1977,39 +1063,36 @@ void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]) | |||
1977 | 1063 | ||
1978 | \*---------------------------------------------------------------------------*/ | 1064 | \*---------------------------------------------------------------------------*/ |
1979 | 1065 | ||
1980 | int encode_WoE(MODEL *model, float e, float xq[]) | 1066 | int encode_WoE(MODEL *model, float e, float xq[]) { |
1981 | { | 1067 | int i, n1; |
1982 | int i, n1; | 1068 | float x[2]; |
1983 | float x[2]; | 1069 | float err[2]; |
1984 | float err[2]; | 1070 | float w[2]; |
1985 | float w[2]; | ||
1986 | const float *codebook1 = ge_cb[0].cb; | 1071 | const float *codebook1 = ge_cb[0].cb; |
1987 | int nb_entries = ge_cb[0].m; | 1072 | int nb_entries = ge_cb[0].m; |
1988 | int ndim = ge_cb[0].k; | 1073 | int ndim = ge_cb[0].k; |
1989 | 1074 | ||
1990 | assert((1<<WO_E_BITS) == nb_entries); | 1075 | assert((1 << WO_E_BITS) == nb_entries); |
1991 | 1076 | ||
1992 | if (e < 0.0) e = 0; /* occasional small negative energies due LPC round off I guess */ | 1077 | if (e < 0.0) |
1078 | e = 0; /* occasional small negative energies due LPC round off I guess */ | ||
1993 | 1079 | ||
1994 | x[0] = log10f((model->Wo/PI)*4000.0/50.0)/log10f(2); | 1080 | x[0] = log10f((model->Wo / PI) * 4000.0 / 50.0) / log10f(2); |
1995 | x[1] = 10.0*log10f(1e-4 + e); | 1081 | x[1] = 10.0 * log10f(1e-4 + e); |
1996 | 1082 | ||
1997 | compute_weights2(x, xq, w); | 1083 | compute_weights2(x, xq, w); |
1998 | for (i=0;i<ndim;i++) | 1084 | for (i = 0; i < ndim; i++) err[i] = x[i] - ge_coeff[i] * xq[i]; |
1999 | err[i] = x[i]-ge_coeff[i]*xq[i]; | ||
2000 | n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim); | 1085 | n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim); |
2001 | 1086 | ||
2002 | for (i=0;i<ndim;i++) | 1087 | for (i = 0; i < ndim; i++) { |
2003 | { | 1088 | xq[i] = ge_coeff[i] * xq[i] + codebook1[ndim * n1 + i]; |
2004 | xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i]; | 1089 | err[i] -= codebook1[ndim * n1 + i]; |
2005 | err[i] -= codebook1[ndim*n1+i]; | ||
2006 | } | 1090 | } |
2007 | 1091 | ||
2008 | //printf("enc: %f %f (%f)(%f) \n", xq[0], xq[1], e, 10.0*log10(1e-4 + e)); | 1092 | // printf("enc: %f %f (%f)(%f) \n", xq[0], xq[1], e, 10.0*log10(1e-4 + e)); |
2009 | return n1; | 1093 | return n1; |
2010 | } | 1094 | } |
2011 | 1095 | ||
2012 | |||
2013 | /*---------------------------------------------------------------------------*\ | 1096 | /*---------------------------------------------------------------------------*\ |
2014 | 1097 | ||
2015 | FUNCTION....: decode_WoE() | 1098 | FUNCTION....: decode_WoE() |
@@ -2022,21 +1105,19 @@ int encode_WoE(MODEL *model, float e, float xq[]) | |||
2022 | 1105 | ||
2023 | \*---------------------------------------------------------------------------*/ | 1106 | \*---------------------------------------------------------------------------*/ |
2024 | 1107 | ||
2025 | void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1) | 1108 | void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1) { |
2026 | { | 1109 | int i; |
2027 | int i; | ||
2028 | const float *codebook1 = ge_cb[0].cb; | 1110 | const float *codebook1 = ge_cb[0].cb; |
2029 | int ndim = ge_cb[0].k; | 1111 | int ndim = ge_cb[0].k; |
2030 | float Wo_min = c2const->Wo_min; | 1112 | float Wo_min = c2const->Wo_min; |
2031 | float Wo_max = c2const->Wo_max; | 1113 | float Wo_max = c2const->Wo_max; |
2032 | 1114 | ||
2033 | for (i=0;i<ndim;i++) | 1115 | for (i = 0; i < ndim; i++) { |
2034 | { | 1116 | xq[i] = ge_coeff[i] * xq[i] + codebook1[ndim * n1 + i]; |
2035 | xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i]; | ||
2036 | } | 1117 | } |
2037 | 1118 | ||
2038 | //printf("dec: %f %f\n", xq[0], xq[1]); | 1119 | // printf("dec: %f %f\n", xq[0], xq[1]); |
2039 | model->Wo = powf(2.0, xq[0])*(PI*50.0)/4000.0; | 1120 | model->Wo = powf(2.0, xq[0]) * (PI * 50.0) / 4000.0; |
2040 | 1121 | ||
2041 | /* bit errors can make us go out of range leading to all sorts of | 1122 | /* bit errors can make us go out of range leading to all sorts of |
2042 | probs like seg faults */ | 1123 | probs like seg faults */ |
@@ -2044,8 +1125,7 @@ void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1) | |||
2044 | if (model->Wo > Wo_max) model->Wo = Wo_max; | 1125 | if (model->Wo > Wo_max) model->Wo = Wo_max; |
2045 | if (model->Wo < Wo_min) model->Wo = Wo_min; | 1126 | if (model->Wo < Wo_min) model->Wo = Wo_min; |
2046 | 1127 | ||
2047 | model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ | 1128 | model->L = PI / model->Wo; /* if we quantise Wo re-compute L */ |
2048 | 1129 | ||
2049 | *e = POW10F(xq[1]/10.0); | 1130 | *e = POW10F(xq[1] / 10.0); |
2050 | } | 1131 | } |
2051 | |||
@@ -29,113 +29,75 @@ | |||
29 | #include "codec2_fft.h" | 29 | #include "codec2_fft.h" |
30 | #include "comp.h" | 30 | #include "comp.h" |
31 | 31 | ||
32 | #define WO_BITS 7 | 32 | #define WO_BITS 7 |
33 | #define WO_LEVELS (1<<WO_BITS) | 33 | #define WO_LEVELS (1 << WO_BITS) |
34 | #define WO_DT_BITS 3 | 34 | #define WO_DT_BITS 3 |
35 | 35 | ||
36 | #define E_BITS 5 | 36 | #define E_BITS 5 |
37 | #define E_LEVELS (1<<E_BITS) | 37 | #define E_LEVELS (1 << E_BITS) |
38 | #define E_MIN_DB -10.0 | 38 | #define E_MIN_DB -10.0 |
39 | #define E_MAX_DB 40.0 | 39 | #define E_MAX_DB 40.0 |
40 | 40 | ||
41 | #define LSP_SCALAR_INDEXES 10 | 41 | #define LSP_SCALAR_INDEXES 10 |
42 | #define LSPD_SCALAR_INDEXES 10 | 42 | #define LSPD_SCALAR_INDEXES 10 |
43 | #define LSP_PRED_VQ_INDEXES 3 | 43 | #define LSP_PRED_VQ_INDEXES 3 |
44 | #define LSP_DIFF_FREQ_INDEXES 5 | ||
45 | #define LSP_DIFF_TIME_BITS 7 | ||
46 | 44 | ||
47 | #define LSPDT_ALL 0 | 45 | #define WO_E_BITS 8 |
48 | #define LSPDT_LOW 1 | ||
49 | #define LSPDT_HIGH 2 | ||
50 | |||
51 | #define WO_E_BITS 8 | ||
52 | 46 | ||
53 | #define LPCPF_GAMMA 0.5 | 47 | #define LPCPF_GAMMA 0.5 |
54 | #define LPCPF_BETA 0.2 | 48 | #define LPCPF_BETA 0.2 |
55 | 49 | ||
56 | void quantise_init(); | ||
57 | float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order, | 50 | float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order, |
58 | int lsp,float ak[]); | 51 | int lsp, float ak[]); |
59 | void aks_to_M2(codec2_fftr_cfg fftr_fwd_cfg, float ak[], int order, MODEL *model, | 52 | void aks_to_M2(codec2_fftr_cfg fftr_fwd_cfg, float ak[], int order, |
60 | float E, float *snr, int dump, int sim_pf, | 53 | MODEL *model, float E, float *snr, int dump, int sim_pf, int pf, |
61 | int pf, int bass_boost, float beta, float gamma, COMP Aw[]); | 54 | int bass_boost, float beta, float gamma, COMP Aw[]); |
62 | 55 | ||
63 | int encode_Wo(C2CONST *c2const, float Wo, int bits); | 56 | int encode_Wo(C2CONST *c2const, float Wo, int bits); |
64 | float decode_Wo(C2CONST *c2const, int index, int bits); | 57 | float decode_Wo(C2CONST *c2const, int index, int bits); |
65 | int encode_log_Wo(C2CONST *c2const, float Wo, int bits); | 58 | int encode_log_Wo(C2CONST *c2const, float Wo, int bits); |
66 | float decode_log_Wo(C2CONST *c2const, int index, int bits); | 59 | float decode_log_Wo(C2CONST *c2const, int index, int bits); |
67 | #if 0 | 60 | void encode_lsps_scalar(int indexes[], float lsp[], int order); |
68 | int encode_Wo_dt(C2CONST *c2const, float Wo, float prev_Wo); | 61 | void decode_lsps_scalar(float lsp[], int indexes[], int order); |
69 | float decode_Wo_dt(C2CONST *c2const, int index, float prev_Wo); | 62 | void encode_lspds_scalar(int indexes[], float lsp[], int order); |
70 | #endif | 63 | void decode_lspds_scalar(float lsp[], int indexes[], int order); |
71 | void encode_lsps_scalar(int indexes[], float lsp[], int order); | ||
72 | void decode_lsps_scalar(float lsp[], int indexes[], int order); | ||
73 | void encode_lspds_scalar(int indexes[], float lsp[], int order); | ||
74 | void decode_lspds_scalar(float lsp[], int indexes[], int order); | ||
75 | void encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order); | ||
76 | void decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order); | ||
77 | void encode_lsps_diff_time(int indexes[], | ||
78 | float lsp[], | ||
79 | float lsp__prev[], | ||
80 | int order); | ||
81 | void decode_lsps_diff_time(float lsp_[], | ||
82 | int indexes[], | ||
83 | float lsp__prev[], | ||
84 | int order); | ||
85 | 64 | ||
86 | void encode_lsps_vq(int *indexes, float *x, float *xq, int order); | 65 | void encode_lsps_vq(int *indexes, float *x, float *xq, int order); |
87 | void decode_lsps_vq(int *indexes, float *xq, int order, int stages); | 66 | void decode_lsps_vq(int *indexes, float *xq, int order, int stages); |
88 | 67 | ||
89 | long quantise(const float * cb, float vec[], float w[], int k, int m, float *se); | 68 | long quantise(const float *cb, float vec[], float w[], int k, int m, float *se); |
90 | void lspvq_quantise(float lsp[], float lsp_[], int order); | 69 | void lspvq_quantise(float lsp[], float lsp_[], int order); |
91 | void lspjnd_quantise(float lsp[], float lsp_[], int order); | 70 | void lspjmv_quantise(float lsps[], float lsps_[], int order); |
92 | void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode); | ||
93 | void lspjvm_quantise(float lsps[], float lsps_[], int order); | ||
94 | void lspanssi_quantise(float lsps[], float lsps_[], int order, int mbest_entries); | ||
95 | float lspmelvq_quantise(float *x, float *xq, int order); | ||
96 | |||
97 | float lspmelvq_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries); | ||
98 | void lspmelvq_decode(int *indexes, float *xq, int ndim); | ||
99 | |||
100 | void encode_mels_scalar(int mel_indexes[], float mels[], int order); | ||
101 | void decode_mels_scalar(float mels[], int mel_indexes[], int order); | ||
102 | 71 | ||
103 | void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]); | 72 | void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]); |
104 | int encode_WoE(MODEL *model, float e, float xq[]); | 73 | int encode_WoE(MODEL *model, float e, float xq[]); |
105 | void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1); | 74 | void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1); |
106 | 75 | ||
107 | int encode_energy(float e, int bits); | 76 | int encode_energy(float e, int bits); |
108 | float decode_energy(int index, int bits); | 77 | float decode_energy(int index, int bits); |
109 | 78 | ||
110 | void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits); | 79 | void pack(unsigned char *bits, unsigned int *nbit, int index, |
111 | void pack_natural_or_gray(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits, unsigned int gray); | 80 | unsigned int index_bits); |
112 | int unpack(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits); | 81 | void pack_natural_or_gray(unsigned char *bits, unsigned int *nbit, int index, |
113 | int unpack_natural_or_gray(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits, unsigned int gray); | 82 | unsigned int index_bits, unsigned int gray); |
83 | int unpack(const unsigned char *bits, unsigned int *nbit, | ||
84 | unsigned int index_bits); | ||
85 | int unpack_natural_or_gray(const unsigned char *bits, unsigned int *nbit, | ||
86 | unsigned int index_bits, unsigned int gray); | ||
114 | 87 | ||
115 | int lsp_bits(int i); | 88 | int lsp_bits(int i); |
116 | int lspd_bits(int i); | 89 | int lspd_bits(int i); |
117 | int lspdt_bits(int i); | ||
118 | int lsp_pred_vq_bits(int i); | 90 | int lsp_pred_vq_bits(int i); |
119 | int mel_bits(int i); | ||
120 | int lspmelvq_cb_bits(int i); | ||
121 | 91 | ||
122 | void apply_lpc_correction(MODEL *model); | 92 | void apply_lpc_correction(MODEL *model); |
123 | float speech_to_uq_lsps(float lsp[], | 93 | float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], |
124 | float ak[], | 94 | int m_pitch, int order); |
125 | float Sn[], | ||
126 | float w[], | ||
127 | int m_pitch, | ||
128 | int order | ||
129 | ); | ||
130 | int check_lsp_order(float lsp[], int lpc_order); | 95 | int check_lsp_order(float lsp[], int lpc_order); |
131 | void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high); | 96 | void bw_expand_lsps(float lsp[], int order, float min_sep_low, |
97 | float min_sep_high); | ||
132 | void bw_expand_lsps2(float lsp[], int order); | 98 | void bw_expand_lsps2(float lsp[], int order); |
133 | void locate_lsps_jnd_steps(float lsp[], int order); | 99 | void locate_lsps_jnd_steps(float lsp[], int order); |
134 | float decode_amplitudes(MODEL *model, | 100 | float decode_amplitudes(MODEL *model, float ak[], int lsp_indexes[], |
135 | float ak[], | 101 | int energy_index, float lsps[], float *e); |
136 | int lsp_indexes[], | ||
137 | int energy_index, | ||
138 | float lsps[], | ||
139 | float *e); | ||
140 | 102 | ||
141 | #endif | 103 | #endif |
@@ -27,64 +27,66 @@ | |||
27 | 27 | ||
28 | /*---------------------------------------------------------------------------*\ | 28 | /*---------------------------------------------------------------------------*\ |
29 | 29 | ||
30 | INCLUDES | 30 | INCLUDES |
31 | 31 | ||
32 | \*---------------------------------------------------------------------------*/ | 32 | \*---------------------------------------------------------------------------*/ |
33 | 33 | ||
34 | #include <stdlib.h> | 34 | #include "sine.h" |
35 | #include <stdio.h> | 35 | |
36 | #include <math.h> | 36 | #include <math.h> |
37 | #include <stdio.h> | ||
38 | #include <stdlib.h> | ||
37 | 39 | ||
38 | #include "defines.h" | 40 | #include "defines.h" |
39 | #include "sine.h" | ||
40 | #include "kiss_fft.h" | 41 | #include "kiss_fft.h" |
41 | 42 | ||
42 | #define HPF_BETA 0.125 | 43 | #define HPF_BETA 0.125 |
43 | 44 | ||
44 | /*---------------------------------------------------------------------------*\ | 45 | /*---------------------------------------------------------------------------*\ |
45 | 46 | ||
46 | HEADERS | 47 | HEADERS |
47 | 48 | ||
48 | \*---------------------------------------------------------------------------*/ | 49 | \*---------------------------------------------------------------------------*/ |
49 | 50 | ||
50 | void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, | 51 | void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, |
51 | float pstep); | 52 | float pstep); |
52 | 53 | ||
53 | /*---------------------------------------------------------------------------*\ | 54 | /*---------------------------------------------------------------------------*\ |
54 | 55 | ||
55 | FUNCTIONS | 56 | FUNCTIONS |
56 | 57 | ||
57 | \*---------------------------------------------------------------------------*/ | 58 | \*---------------------------------------------------------------------------*/ |
58 | 59 | ||
59 | C2CONST c2const_create(int Fs, float framelength_s) { | 60 | C2CONST c2const_create(int Fs, float framelength_s) { |
60 | C2CONST c2const; | 61 | C2CONST c2const; |
61 | 62 | ||
62 | assert((Fs == 8000) || (Fs = 16000)); | 63 | assert((Fs == 8000) || (Fs == 16000)); |
63 | c2const.Fs = Fs; | 64 | c2const.Fs = Fs; |
64 | c2const.n_samp = round(Fs*framelength_s); | 65 | c2const.n_samp = round(Fs * framelength_s); |
65 | c2const.max_amp = floor(Fs*P_MIN_S/2); | 66 | c2const.max_amp = floor(Fs * P_MAX_S / 2); |
66 | c2const.p_min = floor(Fs*P_MIN_S); | 67 | c2const.p_min = floor(Fs * P_MIN_S); |
67 | c2const.p_max = floor(Fs*P_MAX_S); | 68 | c2const.p_max = floor(Fs * P_MAX_S); |
68 | c2const.m_pitch = floor(Fs*M_PITCH_S); | 69 | c2const.m_pitch = floor(Fs * M_PITCH_S); |
69 | c2const.Wo_min = TWO_PI/c2const.p_max; | 70 | c2const.Wo_min = TWO_PI / c2const.p_max; |
70 | c2const.Wo_max = TWO_PI/c2const.p_min; | 71 | c2const.Wo_max = TWO_PI / c2const.p_min; |
71 | 72 | ||
72 | if (Fs == 8000) { | 73 | if (Fs == 8000) { |
73 | c2const.nw = 279; | 74 | c2const.nw = 279; |
74 | } else { | 75 | } else { |
75 | c2const.nw = 511; /* actually a bit shorter in time but lets us maintain constant FFT size */ | 76 | c2const.nw = 511; /* actually a bit shorter in time but lets us maintain |
76 | } | 77 | constant FFT size */ |
78 | } | ||
77 | 79 | ||
78 | c2const.tw = Fs*TW_S; | 80 | c2const.tw = Fs * TW_S; |
79 | 81 | ||
80 | /* | 82 | /* |
81 | fprintf(stderr, "max_amp: %d m_pitch: %d\n", c2const.n_samp, c2const.m_pitch); | 83 | fprintf(stderr, "max_amp: %d m_pitch: %d\n", c2const.n_samp, c2const.m_pitch); |
82 | fprintf(stderr, "p_min: %d p_max: %d\n", c2const.p_min, c2const.p_max); | 84 | fprintf(stderr, "p_min: %d p_max: %d\n", c2const.p_min, c2const.p_max); |
83 | fprintf(stderr, "Wo_min: %f Wo_max: %f\n", c2const.Wo_min, c2const.Wo_max); | 85 | fprintf(stderr, "Wo_min: %f Wo_max: %f\n", c2const.Wo_min, c2const.Wo_max); |
84 | fprintf(stderr, "nw: %d tw: %d\n", c2const.nw, c2const.tw); | 86 | fprintf(stderr, "nw: %d tw: %d\n", c2const.nw, c2const.tw); |
85 | */ | 87 | */ |
86 | 88 | ||
87 | return c2const; | 89 | return c2const; |
88 | } | 90 | } |
89 | 91 | ||
90 | /*---------------------------------------------------------------------------*\ | 92 | /*---------------------------------------------------------------------------*\ |
@@ -97,13 +99,13 @@ C2CONST c2const_create(int Fs, float framelength_s) { | |||
97 | 99 | ||
98 | \*---------------------------------------------------------------------------*/ | 100 | \*---------------------------------------------------------------------------*/ |
99 | 101 | ||
100 | void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], float W[]) | 102 | void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, |
101 | { | 103 | float w[], float W[]) { |
102 | float m; | 104 | float m; |
103 | COMP wshift[FFT_ENC]; | 105 | COMP wshift[FFT_ENC]; |
104 | int i,j; | 106 | int i, j; |
105 | int m_pitch = c2const->m_pitch; | 107 | int m_pitch = c2const->m_pitch; |
106 | int nw = c2const->nw; | 108 | int nw = c2const->nw; |
107 | 109 | ||
108 | /* | 110 | /* |
109 | Generate Hamming window centered on M-sample pitch analysis window | 111 | Generate Hamming window centered on M-sample pitch analysis window |
@@ -117,20 +119,18 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[ | |||
117 | */ | 119 | */ |
118 | 120 | ||
119 | m = 0.0; | 121 | m = 0.0; |
120 | for(i=0; i<m_pitch/2-nw/2; i++) | 122 | for (i = 0; i < m_pitch / 2 - nw / 2; i++) w[i] = 0.0; |
121 | w[i] = 0.0; | 123 | for (i = m_pitch / 2 - nw / 2, j = 0; i < m_pitch / 2 + nw / 2; i++, j++) { |
122 | for(i=m_pitch/2-nw/2,j=0; i<m_pitch/2+nw/2; i++,j++) { | 124 | w[i] = 0.5 - 0.5 * cosf(TWO_PI * j / (nw - 1)); |
123 | w[i] = 0.5 - 0.5*cosf(TWO_PI*j/(nw-1)); | 125 | m += w[i] * w[i]; |
124 | m += w[i]*w[i]; | ||
125 | } | 126 | } |
126 | for(i=m_pitch/2+nw/2; i<m_pitch; i++) | 127 | for (i = m_pitch / 2 + nw / 2; i < m_pitch; i++) w[i] = 0.0; |
127 | w[i] = 0.0; | ||
128 | 128 | ||
129 | /* Normalise - makes freq domain amplitude estimation straight | 129 | /* Normalise - makes freq domain amplitude estimation straight |
130 | forward */ | 130 | forward */ |
131 | 131 | ||
132 | m = 1.0/sqrtf(m*FFT_ENC); | 132 | m = 1.0 / sqrtf(m * FFT_ENC); |
133 | for(i=0; i<m_pitch; i++) { | 133 | for (i = 0; i < m_pitch; i++) { |
134 | w[i] *= m; | 134 | w[i] *= m; |
135 | } | 135 | } |
136 | 136 | ||
@@ -157,14 +157,13 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[ | |||
157 | 157 | ||
158 | COMP temp[FFT_ENC]; | 158 | COMP temp[FFT_ENC]; |
159 | 159 | ||
160 | for(i=0; i<FFT_ENC; i++) { | 160 | for (i = 0; i < FFT_ENC; i++) { |
161 | wshift[i].real = 0.0; | 161 | wshift[i].real = 0.0; |
162 | wshift[i].imag = 0.0; | 162 | wshift[i].imag = 0.0; |
163 | } | 163 | } |
164 | for(i=0; i<nw/2; i++) | 164 | for (i = 0; i < nw / 2; i++) wshift[i].real = w[i + m_pitch / 2]; |
165 | wshift[i].real = w[i+m_pitch/2]; | 165 | for (i = FFT_ENC - nw / 2, j = m_pitch / 2 - nw / 2; i < FFT_ENC; i++, j++) |
166 | for(i=FFT_ENC-nw/2,j=m_pitch/2-nw/2; i<FFT_ENC; i++,j++) | 166 | wshift[i].real = w[j]; |
167 | wshift[i].real = w[j]; | ||
168 | 167 | ||
169 | codec2_fft(fft_fwd_cfg, wshift, temp); | 168 | codec2_fft(fft_fwd_cfg, wshift, temp); |
170 | 169 | ||
@@ -191,12 +190,10 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[ | |||
191 | 190 | ||
192 | */ | 191 | */ |
193 | 192 | ||
194 | 193 | for (i = 0; i < FFT_ENC / 2; i++) { | |
195 | for(i=0; i<FFT_ENC/2; i++) { | 194 | W[i] = temp[i + FFT_ENC / 2].real; |
196 | W[i] = temp[i + FFT_ENC / 2].real; | 195 | W[i + FFT_ENC / 2] = temp[i].real; |
197 | W[i + FFT_ENC / 2] = temp[i].real; | ||
198 | } | 196 | } |
199 | |||
200 | } | 197 | } |
201 | 198 | ||
202 | /*---------------------------------------------------------------------------*\ | 199 | /*---------------------------------------------------------------------------*\ |
@@ -211,12 +208,11 @@ void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[ | |||
211 | 208 | ||
212 | \*---------------------------------------------------------------------------*/ | 209 | \*---------------------------------------------------------------------------*/ |
213 | 210 | ||
214 | float hpf(float x, float states[]) | 211 | float hpf(float x, float states[]) { |
215 | { | 212 | states[0] = -HPF_BETA * states[0] + x - states[1]; |
216 | states[0] = -HPF_BETA*states[0] + x - states[1]; | 213 | states[1] = x; |
217 | states[1] = x; | ||
218 | 214 | ||
219 | return states[0]; | 215 | return states[0]; |
220 | } | 216 | } |
221 | 217 | ||
222 | /*---------------------------------------------------------------------------*\ | 218 | /*---------------------------------------------------------------------------*\ |
@@ -230,41 +226,43 @@ float hpf(float x, float states[]) | |||
230 | \*---------------------------------------------------------------------------*/ | 226 | \*---------------------------------------------------------------------------*/ |
231 | 227 | ||
232 | // TODO: we can either go for a faster FFT using fftr and some stack usage | 228 | // TODO: we can either go for a faster FFT using fftr and some stack usage |
233 | // or we can reduce stack usage to almost zero on STM32 by switching to fft_inplace | 229 | // or we can reduce stack usage to almost zero on STM32 by switching to |
230 | // fft_inplace | ||
234 | #if 1 | 231 | #if 1 |
235 | void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]) | 232 | void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], |
236 | { | 233 | float Sn[], float w[]) { |
237 | int i; | 234 | int i; |
238 | int m_pitch = c2const->m_pitch; | 235 | int m_pitch = c2const->m_pitch; |
239 | int nw = c2const->nw; | 236 | int nw = c2const->nw; |
240 | 237 | ||
241 | for(i=0; i<FFT_ENC; i++) { | 238 | for (i = 0; i < FFT_ENC; i++) { |
242 | Sw[i].real = 0.0; | 239 | Sw[i].real = 0.0; |
243 | Sw[i].imag = 0.0; | 240 | Sw[i].imag = 0.0; |
244 | } | 241 | } |
245 | 242 | ||
246 | /* Centre analysis window on time axis, we need to arrange input | 243 | /* Centre analysis window on time axis, we need to arrange input |
247 | to FFT this way to make FFT phases correct */ | 244 | to FFT this way to make FFT phases correct */ |
248 | 245 | ||
249 | /* move 2nd half to start of FFT input vector */ | 246 | /* move 2nd half to start of FFT input vector */ |
250 | 247 | ||
251 | for(i=0; i<nw/2; i++) | 248 | for (i = 0; i < nw / 2; i++) |
252 | Sw[i].real = Sn[i+m_pitch/2]*w[i+m_pitch/2]; | 249 | Sw[i].real = Sn[i + m_pitch / 2] * w[i + m_pitch / 2]; |
253 | 250 | ||
254 | /* move 1st half to end of FFT input vector */ | 251 | /* move 1st half to end of FFT input vector */ |
255 | 252 | ||
256 | for(i=0; i<nw/2; i++) | 253 | for (i = 0; i < nw / 2; i++) |
257 | Sw[FFT_ENC-nw/2+i].real = Sn[i+m_pitch/2-nw/2]*w[i+m_pitch/2-nw/2]; | 254 | Sw[FFT_ENC - nw / 2 + i].real = |
255 | Sn[i + m_pitch / 2 - nw / 2] * w[i + m_pitch / 2 - nw / 2]; | ||
258 | 256 | ||
259 | codec2_fft_inplace(fft_fwd_cfg, Sw); | 257 | codec2_fft_inplace(fft_fwd_cfg, Sw); |
260 | } | 258 | } |
261 | #else | 259 | #else |
262 | void dft_speech(codec2_fftr_cfg fftr_fwd_cfg, COMP Sw[], float Sn[], float w[]) | 260 | void dft_speech(codec2_fftr_cfg fftr_fwd_cfg, COMP Sw[], float Sn[], |
263 | { | 261 | float w[]) { |
264 | int i; | 262 | int i; |
265 | float sw[FFT_ENC]; | 263 | float sw[FFT_ENC]; |
266 | 264 | ||
267 | for(i=0; i<FFT_ENC; i++) { | 265 | for (i = 0; i < FFT_ENC; i++) { |
268 | sw[i] = 0.0; | 266 | sw[i] = 0.0; |
269 | } | 267 | } |
270 | 268 | ||
@@ -273,19 +271,18 @@ void dft_speech(codec2_fftr_cfg fftr_fwd_cfg, COMP Sw[], float Sn[], float w[]) | |||
273 | 271 | ||
274 | /* move 2nd half to start of FFT input vector */ | 272 | /* move 2nd half to start of FFT input vector */ |
275 | 273 | ||
276 | for(i=0; i<nw/2; i++) | 274 | for (i = 0; i < nw / 2; i++) sw[i] = Sn[i + m_pitch / 2] * w[i + m_pitch / 2]; |
277 | sw[i] = Sn[i+m_pitch/2]*w[i+m_pitch/2]; | ||
278 | 275 | ||
279 | /* move 1st half to end of FFT input vector */ | 276 | /* move 1st half to end of FFT input vector */ |
280 | 277 | ||
281 | for(i=0; i<nw/2; i++) | 278 | for (i = 0; i < nw / 2; i++) |
282 | sw[FFT_ENC-nw/2+i] = Sn[i+m_pitch/2-nw/2]*w[i+m_pitch/2-nw/2]; | 279 | sw[FFT_ENC - nw / 2 + i] = |
280 | Sn[i + m_pitch / 2 - nw / 2] * w[i + m_pitch / 2 - nw / 2]; | ||
283 | 281 | ||
284 | codec2_fftr(fftr_fwd_cfg, sw, Sw); | 282 | codec2_fftr(fftr_fwd_cfg, sw, Sw); |
285 | } | 283 | } |
286 | #endif | 284 | #endif |
287 | 285 | ||
288 | |||
289 | /*---------------------------------------------------------------------------*\ | 286 | /*---------------------------------------------------------------------------*\ |
290 | 287 | ||
291 | FUNCTION....: two_stage_pitch_refinement | 288 | FUNCTION....: two_stage_pitch_refinement |
@@ -297,38 +294,35 @@ void dft_speech(codec2_fftr_cfg fftr_fwd_cfg, COMP Sw[], float Sn[], float w[]) | |||
297 | 294 | ||
298 | \*---------------------------------------------------------------------------*/ | 295 | \*---------------------------------------------------------------------------*/ |
299 | 296 | ||
300 | void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]) | 297 | void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]) { |
301 | { | 298 | float pmin, pmax, pstep; /* pitch refinement minimum, maximum and step */ |
302 | float pmin,pmax,pstep; /* pitch refinment minimum, maximum and step */ | ||
303 | 299 | ||
304 | /* Coarse refinement */ | 300 | /* Coarse refinement */ |
305 | 301 | ||
306 | pmax = TWO_PI/model->Wo + 5; | 302 | pmax = TWO_PI / model->Wo + 5; |
307 | pmin = TWO_PI/model->Wo - 5; | 303 | pmin = TWO_PI / model->Wo - 5; |
308 | pstep = 1.0; | 304 | pstep = 1.0; |
309 | hs_pitch_refinement(model,Sw,pmin,pmax,pstep); | 305 | hs_pitch_refinement(model, Sw, pmin, pmax, pstep); |
310 | 306 | ||
311 | /* Fine refinement */ | 307 | /* Fine refinement */ |
312 | 308 | ||
313 | pmax = TWO_PI/model->Wo + 1; | 309 | pmax = TWO_PI / model->Wo + 1; |
314 | pmin = TWO_PI/model->Wo - 1; | 310 | pmin = TWO_PI / model->Wo - 1; |
315 | pstep = 0.25; | 311 | pstep = 0.25; |
316 | hs_pitch_refinement(model,Sw,pmin,pmax,pstep); | 312 | hs_pitch_refinement(model, Sw, pmin, pmax, pstep); |
317 | 313 | ||
318 | /* Limit range */ | 314 | /* Limit range */ |
319 | 315 | ||
320 | if (model->Wo < TWO_PI/c2const->p_max) | 316 | if (model->Wo < TWO_PI / c2const->p_max) model->Wo = TWO_PI / c2const->p_max; |
321 | model->Wo = TWO_PI/c2const->p_max; | 317 | if (model->Wo > TWO_PI / c2const->p_min) model->Wo = TWO_PI / c2const->p_min; |
322 | if (model->Wo > TWO_PI/c2const->p_min) | ||
323 | model->Wo = TWO_PI/c2const->p_min; | ||
324 | 318 | ||
325 | model->L = floorf(PI/model->Wo); | 319 | model->L = floorf(PI / model->Wo); |
326 | 320 | ||
327 | /* trap occasional round off issues with floorf() */ | 321 | /* trap occasional round off issues with floorf() */ |
328 | if (model->Wo*model->L >= 0.95*PI) { | 322 | if (model->Wo * model->L >= 0.95 * PI) { |
329 | model->L--; | 323 | model->L--; |
330 | } | 324 | } |
331 | assert(model->Wo*model->L < PI); | 325 | assert(model->Wo * model->L < PI); |
332 | } | 326 | } |
333 | 327 | ||
334 | /*---------------------------------------------------------------------------*\ | 328 | /*---------------------------------------------------------------------------*\ |
@@ -348,35 +342,39 @@ void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]) | |||
348 | 342 | ||
349 | \*---------------------------------------------------------------------------*/ | 343 | \*---------------------------------------------------------------------------*/ |
350 | 344 | ||
351 | void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float pstep) | 345 | void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, |
352 | { | 346 | float pstep) { |
353 | int m; /* loop variable */ | 347 | int m; /* loop variable */ |
354 | int b; /* bin for current harmonic centre */ | 348 | int b; /* bin for current harmonic centre */ |
355 | float E; /* energy for current pitch*/ | 349 | float E; /* energy for current pitch*/ |
356 | float Wo; /* current "test" fundamental freq. */ | 350 | float Wo; /* current "test" fundamental freq. */ |
357 | float Wom; /* Wo that maximises E */ | 351 | float Wom; /* Wo that maximises E */ |
358 | float Em; /* mamimum energy */ | 352 | float Em; /* mamimum energy */ |
359 | float r, one_on_r; /* number of rads/bin */ | 353 | float r, one_on_r; /* number of rads/bin */ |
360 | float p; /* current pitch */ | 354 | float p; /* current pitch */ |
361 | 355 | ||
362 | /* Initialisation */ | 356 | /* Initialisation */ |
363 | 357 | ||
364 | model->L = PI/model->Wo; /* use initial pitch est. for L */ | 358 | model->L = PI / model->Wo; /* use initial pitch est. for L */ |
365 | Wom = model->Wo; | 359 | Wom = model->Wo; |
366 | Em = 0.0; | 360 | Em = 0.0; |
367 | r = TWO_PI/FFT_ENC; | 361 | r = TWO_PI / FFT_ENC; |
368 | one_on_r = 1.0/r; | 362 | one_on_r = 1.0 / r; |
369 | 363 | ||
370 | /* Determine harmonic sum for a range of Wo values */ | 364 | /* Determine harmonic sum for a range of Wo values */ |
371 | 365 | ||
372 | for(p=pmin; p<=pmax; p+=pstep) { | 366 | for (p = pmin; p <= pmax; p += pstep) { |
373 | E = 0.0; | 367 | E = 0.0; |
374 | Wo = TWO_PI/p; | 368 | Wo = TWO_PI / p; |
369 | |||
370 | float bFloat = Wo * one_on_r; | ||
371 | float currentBFloat = bFloat; | ||
375 | 372 | ||
376 | /* Sum harmonic magnitudes */ | 373 | /* Sum harmonic magnitudes */ |
377 | for(m=1; m<=model->L; m++) { | 374 | for (m = 1; m <= model->L; m++) { |
378 | b = (int)(m*Wo*one_on_r + 0.5); | 375 | b = (int)(currentBFloat + 0.5); |
379 | E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag; | 376 | E += Sw[b].real * Sw[b].real + Sw[b].imag * Sw[b].imag; |
377 | currentBFloat += bFloat; | ||
380 | } | 378 | } |
381 | /* Compare to see if this is a maximum */ | 379 | /* Compare to see if this is a maximum */ |
382 | 380 | ||
@@ -399,35 +397,35 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float | |||
399 | 397 | ||
400 | \*---------------------------------------------------------------------------*/ | 398 | \*---------------------------------------------------------------------------*/ |
401 | 399 | ||
402 | void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase) | 400 | void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase) { |
403 | { | 401 | int i, m; /* loop variables */ |
404 | int i,m; /* loop variables */ | 402 | int am, bm; /* bounds of current harmonic */ |
405 | int am,bm; /* bounds of current harmonic */ | 403 | float den; /* denominator of amplitude expression */ |
406 | float den; /* denominator of amplitude expression */ | ||
407 | 404 | ||
408 | float r = TWO_PI/FFT_ENC; | 405 | float r = TWO_PI / FFT_ENC; |
409 | float one_on_r = 1.0/r; | 406 | float one_on_r = 1.0 / r; |
410 | 407 | ||
411 | for(m=1; m<=model->L; m++) { | 408 | for (m = 1; m <= model->L; m++) { |
412 | /* Estimate ampltude of harmonic */ | 409 | /* Estimate ampltude of harmonic */ |
413 | 410 | ||
414 | den = 0.0; | 411 | den = 0.0; |
415 | am = (int)((m - 0.5)*model->Wo*one_on_r + 0.5); | 412 | am = (int)((m - 0.5) * model->Wo * one_on_r + 0.5); |
416 | bm = (int)((m + 0.5)*model->Wo*one_on_r + 0.5); | 413 | bm = (int)((m + 0.5) * model->Wo * one_on_r + 0.5); |
417 | 414 | ||
418 | for(i=am; i<bm; i++) { | 415 | for (i = am; i < bm; i++) { |
419 | den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag; | 416 | den += Sw[i].real * Sw[i].real + Sw[i].imag * Sw[i].imag; |
420 | } | 417 | } |
421 | 418 | ||
422 | model->A[m] = sqrtf(den); | 419 | model->A[m] = sqrtf(den); |
423 | 420 | ||
424 | if (est_phase) { | 421 | if (est_phase) { |
425 | int b = (int)(m*model->Wo/r + 0.5); /* DFT bin of centre of current harmonic */ | 422 | int b = (int)(m * model->Wo / r + |
423 | 0.5); /* DFT bin of centre of current harmonic */ | ||
426 | 424 | ||
427 | /* Estimate phase of harmonic, this is expensive in CPU for | 425 | /* Estimate phase of harmonic, this is expensive in CPU for |
428 | embedded devicesso we make it an option */ | 426 | embedded devicesso we make it an option */ |
429 | 427 | ||
430 | model->phi[m] = atan2f(Sw[b].imag,Sw[b].real); | 428 | model->phi[m] = atan2f(Sw[b].imag, Sw[b].real); |
431 | } | 429 | } |
432 | } | 430 | } |
433 | } | 431 | } |
@@ -443,119 +441,110 @@ void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase) | |||
443 | 441 | ||
444 | \*---------------------------------------------------------------------------*/ | 442 | \*---------------------------------------------------------------------------*/ |
445 | 443 | ||
446 | float est_voicing_mbe( | 444 | float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], float W[]) { |
447 | C2CONST *c2const, | 445 | int l, al, bl, m; /* loop variables */ |
448 | MODEL *model, | 446 | COMP Am; /* amplitude sample for this band */ |
449 | COMP Sw[], | 447 | int offset; /* centers Hw[] about current harmonic */ |
450 | float W[] | 448 | float den; /* denominator of Am expression */ |
451 | ) | 449 | float error; /* accumulated error between original and synthesised */ |
452 | { | 450 | float Wo; |
453 | int l,al,bl,m; /* loop variables */ | 451 | float sig, snr; |
454 | COMP Am; /* amplitude sample for this band */ | 452 | float elow, ehigh, eratio; |
455 | int offset; /* centers Hw[] about current harmonic */ | 453 | float sixty; |
456 | float den; /* denominator of Am expression */ | 454 | COMP Ew; |
457 | float error; /* accumulated error between original and synthesised */ | 455 | Ew.real = 0; |
458 | float Wo; | 456 | Ew.imag = 0; |
459 | float sig, snr; | 457 | |
460 | float elow, ehigh, eratio; | 458 | int l_1000hz = model->L * 1000.0 / (c2const->Fs / 2); |
461 | float sixty; | 459 | sig = 1E-4; |
462 | COMP Ew; | 460 | for (l = 1; l <= l_1000hz; l++) { |
463 | Ew.real = 0; | 461 | sig += model->A[l] * model->A[l]; |
464 | Ew.imag = 0; | 462 | } |
465 | |||
466 | int l_1000hz = model->L*1000.0/(c2const->Fs/2); | ||
467 | sig = 1E-4; | ||
468 | for(l=1; l<=l_1000hz; l++) { | ||
469 | sig += model->A[l]*model->A[l]; | ||
470 | } | ||
471 | 463 | ||
472 | Wo = model->Wo; | 464 | Wo = model->Wo; |
473 | error = 1E-4; | 465 | error = 1E-4; |
474 | 466 | ||
475 | /* Just test across the harmonics in the first 1000 Hz */ | 467 | /* Just test across the harmonics in the first 1000 Hz */ |
476 | 468 | ||
477 | for(l=1; l<=l_1000hz; l++) { | 469 | for (l = 1; l <= l_1000hz; l++) { |
478 | Am.real = 0.0; | 470 | Am.real = 0.0; |
479 | Am.imag = 0.0; | 471 | Am.imag = 0.0; |
480 | den = 0.0; | 472 | den = 0.0; |
481 | al = ceilf((l - 0.5)*Wo*FFT_ENC/TWO_PI); | 473 | al = ceilf((l - 0.5) * Wo * FFT_ENC / TWO_PI); |
482 | bl = ceilf((l + 0.5)*Wo*FFT_ENC/TWO_PI); | 474 | bl = ceilf((l + 0.5) * Wo * FFT_ENC / TWO_PI); |
483 | 475 | ||
484 | /* Estimate amplitude of harmonic assuming harmonic is totally voiced */ | 476 | /* Estimate amplitude of harmonic assuming harmonic is totally voiced */ |
485 | 477 | ||
486 | offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5; | 478 | offset = FFT_ENC / 2 - l * Wo * FFT_ENC / TWO_PI + 0.5; |
487 | for(m=al; m<bl; m++) { | 479 | for (m = al; m < bl; m++) { |
488 | Am.real += Sw[m].real*W[offset+m]; | 480 | Am.real += Sw[m].real * W[offset + m]; |
489 | Am.imag += Sw[m].imag*W[offset+m]; | 481 | Am.imag += Sw[m].imag * W[offset + m]; |
490 | den += W[offset+m]*W[offset+m]; | 482 | den += W[offset + m] * W[offset + m]; |
491 | } | 483 | } |
492 | 484 | ||
493 | Am.real = Am.real/den; | 485 | Am.real = Am.real / den; |
494 | Am.imag = Am.imag/den; | 486 | Am.imag = Am.imag / den; |
495 | 487 | ||
496 | /* Determine error between estimated harmonic and original */ | 488 | /* Determine error between estimated harmonic and original */ |
497 | 489 | ||
498 | for(m=al; m<bl; m++) { | 490 | for (m = al; m < bl; m++) { |
499 | Ew.real = Sw[m].real - Am.real*W[offset+m]; | 491 | Ew.real = Sw[m].real - Am.real * W[offset + m]; |
500 | Ew.imag = Sw[m].imag - Am.imag*W[offset+m]; | 492 | Ew.imag = Sw[m].imag - Am.imag * W[offset + m]; |
501 | error += Ew.real*Ew.real; | 493 | error += Ew.real * Ew.real; |
502 | error += Ew.imag*Ew.imag; | 494 | error += Ew.imag * Ew.imag; |
503 | } | ||
504 | } | 495 | } |
496 | } | ||
505 | 497 | ||
506 | snr = 10.0*log10f(sig/error); | 498 | snr = 10.0 * log10f(sig / error); |
507 | if (snr > V_THRESH) | 499 | if (snr > V_THRESH) |
508 | model->voiced = 1; | 500 | model->voiced = 1; |
509 | else | 501 | else |
510 | model->voiced = 0; | 502 | model->voiced = 0; |
511 | 503 | ||
512 | /* post processing, helps clean up some voicing errors ------------------*/ | 504 | /* post processing, helps clean up some voicing errors ------------------*/ |
513 | |||
514 | /* | ||
515 | Determine the ratio of low freqency to high frequency energy, | ||
516 | voiced speech tends to be dominated by low frequency energy, | ||
517 | unvoiced by high frequency. This measure can be used to | ||
518 | determine if we have made any gross errors. | ||
519 | */ | ||
520 | |||
521 | int l_2000hz = model->L*2000.0/(c2const->Fs/2); | ||
522 | int l_4000hz = model->L*4000.0/(c2const->Fs/2); | ||
523 | elow = ehigh = 1E-4; | ||
524 | for(l=1; l<=l_2000hz; l++) { | ||
525 | elow += model->A[l]*model->A[l]; | ||
526 | } | ||
527 | for(l=l_2000hz; l<=l_4000hz; l++) { | ||
528 | ehigh += model->A[l]*model->A[l]; | ||
529 | } | ||
530 | eratio = 10.0*log10f(elow/ehigh); | ||
531 | 505 | ||
532 | /* Look for Type 1 errors, strongly V speech that has been | 506 | /* |
533 | accidentally declared UV */ | 507 | Determine the ratio of low frequency to high frequency energy, |
508 | voiced speech tends to be dominated by low frequency energy, | ||
509 | unvoiced by high frequency. This measure can be used to | ||
510 | determine if we have made any gross errors. | ||
511 | */ | ||
512 | |||
513 | int l_2000hz = model->L * 2000.0 / (c2const->Fs / 2); | ||
514 | int l_4000hz = model->L * 4000.0 / (c2const->Fs / 2); | ||
515 | elow = ehigh = 1E-4; | ||
516 | for (l = 1; l <= l_2000hz; l++) { | ||
517 | elow += model->A[l] * model->A[l]; | ||
518 | } | ||
519 | for (l = l_2000hz; l <= l_4000hz; l++) { | ||
520 | ehigh += model->A[l] * model->A[l]; | ||
521 | } | ||
522 | eratio = 10.0 * log10f(elow / ehigh); | ||
534 | 523 | ||
535 | if (model->voiced == 0) | 524 | /* Look for Type 1 errors, strongly V speech that has been |
536 | if (eratio > 10.0) | 525 | accidentally declared UV */ |
537 | model->voiced = 1; | ||
538 | 526 | ||
539 | /* Look for Type 2 errors, strongly UV speech that has been | 527 | if (model->voiced == 0) |
540 | accidentally declared V */ | 528 | if (eratio > 10.0) model->voiced = 1; |
541 | 529 | ||
542 | if (model->voiced == 1) { | 530 | /* Look for Type 2 errors, strongly UV speech that has been |
543 | if (eratio < -10.0) | 531 | accidentally declared V */ |
544 | model->voiced = 0; | ||
545 | 532 | ||
546 | /* A common source of Type 2 errors is the pitch estimator | 533 | if (model->voiced == 1) { |
547 | gives a low (50Hz) estimate for UV speech, which gives a | 534 | if (eratio < -10.0) model->voiced = 0; |
548 | good match with noise due to the close harmoonic spacing. | ||
549 | These errors are much more common than people with 50Hz3 | ||
550 | pitch, so we have just a small eratio threshold. */ | ||
551 | 535 | ||
552 | sixty = 60.0*TWO_PI/c2const->Fs; | 536 | /* A common source of Type 2 errors is the pitch estimator |
553 | if ((eratio < -4.0) && (model->Wo <= sixty)) | 537 | gives a low (50Hz) estimate for UV speech, which gives a |
554 | model->voiced = 0; | 538 | good match with noise due to the close harmoonic spacing. |
555 | } | 539 | These errors are much more common than people with 50Hz3 |
556 | //printf(" v: %d snr: %f eratio: %3.2f %f\n",model->voiced,snr,eratio,dF0); | 540 | pitch, so we have just a small eratio threshold. */ |
557 | 541 | ||
558 | return snr; | 542 | sixty = 60.0 * TWO_PI / c2const->Fs; |
543 | if ((eratio < -4.0) && (model->Wo <= sixty)) model->voiced = 0; | ||
544 | } | ||
545 | // printf(" v: %d snr: %f eratio: %3.2f %f\n",model->voiced,snr,eratio,dF0); | ||
546 | |||
547 | return snr; | ||
559 | } | 548 | } |
560 | 549 | ||
561 | /*---------------------------------------------------------------------------*\ | 550 | /*---------------------------------------------------------------------------*\ |
@@ -564,32 +553,29 @@ float est_voicing_mbe( | |||
564 | AUTHOR......: David Rowe | 553 | AUTHOR......: David Rowe |
565 | DATE CREATED: 11/5/94 | 554 | DATE CREATED: 11/5/94 |
566 | 555 | ||
567 | Init function that generates the trapezoidal (Parzen) sythesis window. | 556 | Init function that generates the trapezoidal (Parzen) synthesis window. |
568 | 557 | ||
569 | \*---------------------------------------------------------------------------*/ | 558 | \*---------------------------------------------------------------------------*/ |
570 | 559 | ||
571 | void make_synthesis_window(C2CONST *c2const, float Pn[]) | 560 | void make_synthesis_window(C2CONST *c2const, float Pn[]) { |
572 | { | 561 | int i; |
573 | int i; | ||
574 | float win; | 562 | float win; |
575 | int n_samp = c2const->n_samp; | 563 | int n_samp = c2const->n_samp; |
576 | int tw = c2const->tw; | 564 | int tw = c2const->tw; |
577 | 565 | ||
578 | /* Generate Parzen window in time domain */ | 566 | /* Generate Parzen window in time domain */ |
579 | 567 | ||
580 | win = 0.0; | 568 | win = 0.0; |
581 | for(i=0; i<n_samp/2-tw; i++) | 569 | for (i = 0; i < n_samp / 2 - tw; i++) Pn[i] = 0.0; |
582 | Pn[i] = 0.0; | ||
583 | win = 0.0; | 570 | win = 0.0; |
584 | for(i=n_samp/2-tw; i<n_samp/2+tw; win+=1.0/(2*tw), i++ ) | 571 | for (i = n_samp / 2 - tw; i < n_samp / 2 + tw; win += 1.0 / (2 * tw), i++) |
585 | Pn[i] = win; | 572 | Pn[i] = win; |
586 | for(i=n_samp/2+tw; i<3*n_samp/2-tw; i++) | 573 | for (i = n_samp / 2 + tw; i < 3 * n_samp / 2 - tw; i++) Pn[i] = 1.0; |
587 | Pn[i] = 1.0; | ||
588 | win = 1.0; | 574 | win = 1.0; |
589 | for(i=3*n_samp/2-tw; i<3*n_samp/2+tw; win-=1.0/(2*tw), i++) | 575 | for (i = 3 * n_samp / 2 - tw; i < 3 * n_samp / 2 + tw; |
576 | win -= 1.0 / (2 * tw), i++) | ||
590 | Pn[i] = win; | 577 | Pn[i] = win; |
591 | for(i=3*n_samp/2+tw; i<2*n_samp; i++) | 578 | for (i = 3 * n_samp / 2 + tw; i < 2 * n_samp; i++) Pn[i] = 0.0; |
592 | Pn[i] = 0.0; | ||
593 | } | 579 | } |
594 | 580 | ||
595 | /*---------------------------------------------------------------------------*\ | 581 | /*---------------------------------------------------------------------------*\ |
@@ -600,77 +586,72 @@ void make_synthesis_window(C2CONST *c2const, float Pn[]) | |||
600 | 586 | ||
601 | Synthesise a speech signal in the frequency domain from the | 587 | Synthesise a speech signal in the frequency domain from the |
602 | sinusodal model parameters. Uses overlap-add with a trapezoidal | 588 | sinusodal model parameters. Uses overlap-add with a trapezoidal |
603 | window to smoothly interpolate betwen frames. | 589 | window to smoothly interpolate between frames. |
604 | 590 | ||
605 | \*---------------------------------------------------------------------------*/ | 591 | \*---------------------------------------------------------------------------*/ |
606 | 592 | ||
607 | void synthesise( | 593 | void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, |
608 | int n_samp, | 594 | float Sn_[], /* time domain synthesised signal */ |
609 | codec2_fftr_cfg fftr_inv_cfg, | 595 | MODEL *model, /* ptr to model parameters for this frame */ |
610 | float Sn_[], /* time domain synthesised signal */ | 596 | float Pn[], /* time domain Parzen window */ |
611 | MODEL *model, /* ptr to model parameters for this frame */ | 597 | int shift /* flag used to handle transition frames */ |
612 | float Pn[], /* time domain Parzen window */ | 598 | ) { |
613 | int shift /* flag used to handle transition frames */ | 599 | int i, l, j, b; /* loop variables */ |
614 | ) | 600 | COMP Sw_[FFT_DEC / 2 + 1]; /* DFT of synthesised signal */ |
615 | { | 601 | float sw_[FFT_DEC]; /* synthesised signal */ |
616 | int i,l,j,b; /* loop variables */ | 602 | |
617 | COMP Sw_[FFT_DEC/2+1]; /* DFT of synthesised signal */ | 603 | if (shift) { |
618 | float sw_[FFT_DEC]; /* synthesised signal */ | 604 | /* Update memories */ |
619 | 605 | for (i = 0; i < n_samp - 1; i++) { | |
620 | if (shift) { | 606 | Sn_[i] = Sn_[i + n_samp]; |
621 | /* Update memories */ | ||
622 | for(i=0; i<n_samp-1; i++) { | ||
623 | Sn_[i] = Sn_[i+n_samp]; | ||
624 | } | ||
625 | Sn_[n_samp-1] = 0.0; | ||
626 | } | 607 | } |
608 | Sn_[n_samp - 1] = 0.0; | ||
609 | } | ||
627 | 610 | ||
628 | for(i=0; i<FFT_DEC/2+1; i++) { | 611 | for (i = 0; i < FFT_DEC / 2 + 1; i++) { |
629 | Sw_[i].real = 0.0; | 612 | Sw_[i].real = 0.0; |
630 | Sw_[i].imag = 0.0; | 613 | Sw_[i].imag = 0.0; |
631 | } | 614 | } |
632 | 615 | ||
633 | /* Now set up frequency domain synthesised speech */ | 616 | /* Now set up frequency domain synthesised speech */ |
634 | 617 | ||
635 | for(l=1; l<=model->L; l++) { | 618 | for (l = 1; l <= model->L; l++) { |
636 | b = (int)(l*model->Wo*FFT_DEC/TWO_PI + 0.5); | 619 | b = (int)(l * model->Wo * FFT_DEC / TWO_PI + 0.5); |
637 | if (b > ((FFT_DEC/2)-1)) { | 620 | if (b > ((FFT_DEC / 2) - 1)) { |
638 | b = (FFT_DEC/2)-1; | 621 | b = (FFT_DEC / 2) - 1; |
639 | } | ||
640 | Sw_[b].real = model->A[l]*cosf(model->phi[l]); | ||
641 | Sw_[b].imag = model->A[l]*sinf(model->phi[l]); | ||
642 | } | 622 | } |
623 | Sw_[b].real = model->A[l] * cosf(model->phi[l]); | ||
624 | Sw_[b].imag = model->A[l] * sinf(model->phi[l]); | ||
625 | } | ||
643 | 626 | ||
644 | /* Perform inverse DFT */ | 627 | /* Perform inverse DFT */ |
645 | 628 | ||
646 | codec2_fftri(fftr_inv_cfg, Sw_,sw_); | 629 | codec2_fftri(fftr_inv_cfg, Sw_, sw_); |
647 | 630 | ||
648 | /* Overlap add to previous samples */ | 631 | /* Overlap add to previous samples */ |
649 | 632 | ||
650 | #ifdef USE_KISS_FFT | 633 | #ifdef USE_KISS_FFT |
651 | #define FFTI_FACTOR ((float)1.0) | 634 | #define FFTI_FACTOR ((float)1.0) |
652 | #else | 635 | #else |
653 | #define FFTI_FACTOR ((float32_t)FFT_DEC) | 636 | #define FFTI_FACTOR ((float32_t)FFT_DEC) |
654 | #endif | 637 | #endif |
655 | 638 | ||
656 | for(i=0; i<n_samp-1; i++) { | 639 | for (i = 0; i < n_samp - 1; i++) { |
657 | Sn_[i] += sw_[FFT_DEC-n_samp+1+i]*Pn[i] * FFTI_FACTOR; | 640 | Sn_[i] += sw_[FFT_DEC - n_samp + 1 + i] * Pn[i] * FFTI_FACTOR; |
658 | } | 641 | } |
659 | 642 | ||
660 | if (shift) | 643 | if (shift) |
661 | for(i=n_samp-1,j=0; i<2*n_samp; i++,j++) | 644 | for (i = n_samp - 1, j = 0; i < 2 * n_samp; i++, j++) |
662 | Sn_[i] = sw_[j]*Pn[i] * FFTI_FACTOR; | 645 | Sn_[i] = sw_[j] * Pn[i] * FFTI_FACTOR; |
663 | else | 646 | else |
664 | for(i=n_samp-1,j=0; i<2*n_samp; i++,j++) | 647 | for (i = n_samp - 1, j = 0; i < 2 * n_samp; i++, j++) |
665 | Sn_[i] += sw_[j]*Pn[i] * FFTI_FACTOR; | 648 | Sn_[i] += sw_[j] * Pn[i] * FFTI_FACTOR; |
666 | } | 649 | } |
667 | 650 | ||
668 | |||
669 | /* todo: this should probably be in some states rather than a static */ | 651 | /* todo: this should probably be in some states rather than a static */ |
670 | static unsigned long next = 1; | 652 | static unsigned long next = 1; |
671 | 653 | ||
672 | int codec2_rand(void) { | 654 | int codec2_rand(void) { |
673 | next = next * 1103515245 + 12345; | 655 | next = next * 1103515245 + 12345; |
674 | return((unsigned)(next/65536) % 32768); | 656 | return ((unsigned)(next / 65536) % 32768); |
675 | } | 657 | } |
676 | |||
@@ -28,20 +28,23 @@ | |||
28 | #ifndef __SINE__ | 28 | #ifndef __SINE__ |
29 | #define __SINE__ | 29 | #define __SINE__ |
30 | 30 | ||
31 | #include "defines.h" | ||
32 | #include "comp.h" | ||
33 | #include "codec2_fft.h" | 31 | #include "codec2_fft.h" |
32 | #include "comp.h" | ||
33 | #include "defines.h" | ||
34 | 34 | ||
35 | C2CONST c2const_create(int Fs, float framelength_ms); | 35 | C2CONST c2const_create(int Fs, float framelength_ms); |
36 | 36 | ||
37 | void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], float W[]); | 37 | void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, |
38 | float w[], float W[]); | ||
38 | float hpf(float x, float states[]); | 39 | float hpf(float x, float states[]); |
39 | void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]); | 40 | void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], |
41 | float Sn[], float w[]); | ||
40 | void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]); | 42 | void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]); |
41 | void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase); | 43 | void estimate_amplitudes(MODEL *model, COMP Sw[], float W[], int est_phase); |
42 | float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], float W[]); | 44 | float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], float W[]); |
43 | void make_synthesis_window(C2CONST *c2const, float Pn[]); | 45 | void make_synthesis_window(C2CONST *c2const, float Pn[]); |
44 | void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift); | 46 | void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, float Sn_[], |
47 | MODEL *model, float Pn[], int shift); | ||
45 | 48 | ||
46 | #define CODEC2_RAND_MAX 32767 | 49 | #define CODEC2_RAND_MAX 32767 |
47 | int codec2_rand(void); | 50 | int codec2_rand(void); |
diff --git a/stripdown.sh b/stripdown.sh index c8d8332..c91694a 100755 --- a/stripdown.sh +++ b/stripdown.sh | |||
@@ -3,10 +3,10 @@ | |||
3 | BUILDDIR=build_stripped | 3 | BUILDDIR=build_stripped |
4 | DESTDIR=codec2lite | 4 | DESTDIR=codec2lite |
5 | 5 | ||
6 | LIBSRC="codebook.c codebookd.c codebookge.c codebookjvm.c codebooknewamp1.c codebooknewamp1_energy.c codec2.c codec2_fft.c interp.c kiss_fft.c kiss_fftr.c lpc.c lsp.c mbest.c newamp1.c newamp2.c nlp.c pack.c phase.c postfilter.c quantise.c sine.c" | 6 | LIBSRC="codec2.c codec2_fft.c interp.c kiss_fft.c kiss_fftr.c lpc.c lsp.c mbest.c newamp1.c nlp.c pack.c phase.c postfilter.c quantise.c sine.c" |
7 | LIBGENSRC="codebooklspmelvq.c codebookmel.c codebooknewamp2.c codebooknewamp2_energy.c" | 7 | LIBGENSRC="codebook.c codebookd.c codebookge.c codebooknewamp1.c codebooknewamp1_energy.c codebooknewamp2.c codebooknewamp2_energy.c codebookjmv.c" |
8 | 8 | ||
9 | LIBINC="_kiss_fft_guts.h comp_prim.h lpc.h os.h bpf.h lsp.h phase.h bpfb.h defines.h machdep.h postfilter.h mbest.h quantise.h codec2_fft.h interp.h newamp1.h sine.h codec2_internal.h kiss_fft.h newamp2.h comp.h kiss_fftr.h nlp.h" | 9 | LIBINC="_kiss_fft_guts.h comp_prim.h lpc.h os.h bpf.h lsp.h phase.h bpfb.h defines.h machdep.h postfilter.h mbest.h quantise.h codec2_fft.h interp.h newamp1.h sine.h codec2_internal.h kiss_fft.h comp.h kiss_fftr.h nlp.h" |
10 | LIBGENINC="version.h" | 10 | LIBGENINC="version.h" |
11 | 11 | ||
12 | EMPTYINC="c2wideband.h dump.h" | 12 | EMPTYINC="c2wideband.h dump.h" |
@@ -36,7 +36,7 @@ done | |||
36 | 36 | ||
37 | cd ${BUILDDIR} | 37 | cd ${BUILDDIR} |
38 | cmake .. | 38 | cmake .. |
39 | make tnewamp1 | 39 | cmake --build . -t codec2 |
40 | 40 | ||
41 | # copy generated files | 41 | # copy generated files |
42 | for file in ${LIBGENSRC}; do | 42 | for file in ${LIBGENSRC}; do |
@@ -55,10 +55,9 @@ CFLAGS = -Wall -Wno-strict-overflow -std=gnu11 -fPIC -g -O2 -I. -lm | |||
55 | CFLAGS += -DHORUS_L2_RX -DINTERLEAVER -DRUN_TIME_TABLES -DSCRAMBLER -Dcodec2_EXPORTS | 55 | CFLAGS += -DHORUS_L2_RX -DINTERLEAVER -DRUN_TIME_TABLES -DSCRAMBLER -Dcodec2_EXPORTS |
56 | CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers | 56 | CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers |
57 | 57 | ||
58 | LIBSRC=codebook.c codebookd.c codebookge.c codebookmel.c codebooklspmelvq.c codebookjvm.c \ | 58 | LIBSRC=codebook.c codebookd.c codebookge.c codebookjmv.c codebooknewamp1_energy.c \ |
59 | codebooknewamp1.c codebooknewamp1_energy.c codebooknewamp2.c codebooknewamp2_energy.c \ | 59 | codebooknewamp1.c codec2.c codec2_fft.c interp.c kiss_fft.c kiss_fftr.c \ |
60 | codec2.c codec2_fft.c interp.c kiss_fft.c kiss_fftr.c lpc.c lsp.c mbest.c \ | 60 | lpc.c lsp.c mbest.c newamp1.c nlp.c pack.c phase.c postfilter.c quantise.c sine.c |
61 | newamp1.c newamp2.c nlp.c pack.c phase.c postfilter.c quantise.c sine.c | ||
62 | 61 | ||
63 | all: main | 62 | all: main |
64 | 63 | ||
@@ -87,6 +86,8 @@ int main() { | |||
87 | int off = 0; | 86 | int off = 0; |
88 | unsigned char bits[128]; | 87 | unsigned char bits[128]; |
89 | 88 | ||
89 | fprintf(stderr, "%d samples per frame, %d bits per frame\n", nsam, nbit); | ||
90 | |||
90 | fread(input, 976692, 1, f); | 91 | fread(input, 976692, 1, f); |
91 | fclose(f); | 92 | fclose(f); |
92 | 93 | ||
@@ -29,9 +29,9 @@ | |||
29 | #ifndef CODEC2_HAVE_VERSION | 29 | #ifndef CODEC2_HAVE_VERSION |
30 | #define CODEC2_HAVE_VERSION | 30 | #define CODEC2_HAVE_VERSION |
31 | 31 | ||
32 | #define CODEC2_VERSION_MAJOR 0 | 32 | #define CODEC2_VERSION_MAJOR 1 |
33 | #define CODEC2_VERSION_MINOR 9 | 33 | #define CODEC2_VERSION_MINOR 2 |
34 | #define CODEC2_VERSION_PATCH 2 | 34 | /* #undef CODEC2_VERSION_PATCH */ |
35 | #define CODEC2_VERSION "0.9.2" | 35 | #define CODEC2_VERSION "1.2.0" |
36 | 36 | ||
37 | #endif //CODEC2_HAVE_VERSION | 37 | #endif //CODEC2_HAVE_VERSION |