~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/third_party/speex/libspeex/filterbank.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2006 Jean-Marc Valin */
 
2
/**
 
3
   @file filterbank.c
 
4
   @brief Converting between psd and filterbank
 
5
 */
 
6
/*
 
7
   Redistribution and use in source and binary forms, with or without
 
8
   modification, are permitted provided that the following conditions are
 
9
   met:
 
10
 
 
11
   1. Redistributions of source code must retain the above copyright notice,
 
12
   this list of conditions and the following disclaimer.
 
13
 
 
14
   2. Redistributions in binary form must reproduce the above copyright
 
15
   notice, this list of conditions and the following disclaimer in the
 
16
   documentation and/or other materials provided with the distribution.
 
17
 
 
18
   3. The name of the author may not be used to endorse or promote products
 
19
   derived from this software without specific prior written permission.
 
20
 
 
21
   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
22
   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
23
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
24
   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 
25
   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
26
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
27
   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
28
   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
29
   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
30
   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
31
   POSSIBILITY OF SUCH DAMAGE.
 
32
*/
 
33
 
 
34
#ifdef HAVE_CONFIG_H
 
35
#include "config.h"
 
36
#endif
 
37
 
 
38
#include "filterbank.h"
 
39
#include "arch.h"
 
40
#include <math.h>
 
41
#include "math_approx.h"
 
42
#include "os_support.h"
 
43
      
 
44
#ifdef FIXED_POINT
 
45
 
 
46
#define toBARK(n)   (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))
 
47
      
 
48
#else
 
49
#define toBARK(n)   (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
 
50
#endif
 
51
       
 
52
#define toMEL(n)    (2595.f*log10(1.f+(n)/700.f))
 
53
 
 
54
FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
 
55
{
 
56
   FilterBank *bank;
 
57
   spx_word32_t df;
 
58
   spx_word32_t max_mel, mel_interval;
 
59
   int i;
 
60
   int id1;
 
61
   int id2;
 
62
   df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
 
63
   max_mel = toBARK(EXTRACT16(sampling/2));
 
64
   mel_interval = PDIV32(max_mel,banks-1);
 
65
   
 
66
   bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
 
67
   bank->nb_banks = banks;
 
68
   bank->len = len;
 
69
   bank->bank_left = (int*)speex_alloc(len*sizeof(int));
 
70
   bank->bank_right = (int*)speex_alloc(len*sizeof(int));
 
71
   bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
 
72
   bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
 
73
   /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
 
74
#ifndef FIXED_POINT
 
75
   bank->scaling = (float*)speex_alloc(banks*sizeof(float));
 
76
#endif
 
77
   for (i=0;i<len;i++)
 
78
   {
 
79
      spx_word16_t curr_freq;
 
80
      spx_word32_t mel;
 
81
      spx_word16_t val;
 
82
      curr_freq = EXTRACT16(MULT16_32_P15(i,df));
 
83
      mel = toBARK(curr_freq);
 
84
      if (mel > max_mel)
 
85
         break;
 
86
#ifdef FIXED_POINT
 
87
      id1 = DIV32(mel,mel_interval);
 
88
#else      
 
89
      id1 = (int)(floor(mel/mel_interval));
 
90
#endif
 
91
      if (id1>banks-2)
 
92
      {
 
93
         id1 = banks-2;
 
94
         val = Q15_ONE;
 
95
      } else {
 
96
         val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));
 
97
      }
 
98
      id2 = id1+1;
 
99
      bank->bank_left[i] = id1;
 
100
      bank->filter_left[i] = SUB16(Q15_ONE,val);
 
101
      bank->bank_right[i] = id2;
 
102
      bank->filter_right[i] = val;
 
103
   }
 
104
   
 
105
   /* Think I can safely disable normalisation for fixed-point (and probably float as well) */
 
106
#ifndef FIXED_POINT
 
107
   for (i=0;i<bank->nb_banks;i++)
 
108
      bank->scaling[i] = 0;
 
109
   for (i=0;i<bank->len;i++)
 
110
   {
 
111
      int id = bank->bank_left[i];
 
112
      bank->scaling[id] += bank->filter_left[i];
 
113
      id = bank->bank_right[i];
 
114
      bank->scaling[id] += bank->filter_right[i];
 
115
   }
 
116
   for (i=0;i<bank->nb_banks;i++)
 
117
      bank->scaling[i] = Q15_ONE/(bank->scaling[i]);
 
118
#endif
 
119
   return bank;
 
120
}
 
121
 
 
122
void filterbank_destroy(FilterBank *bank)
 
123
{
 
124
   speex_free(bank->bank_left);
 
125
   speex_free(bank->bank_right);
 
126
   speex_free(bank->filter_left);
 
127
   speex_free(bank->filter_right);
 
128
#ifndef FIXED_POINT
 
129
   speex_free(bank->scaling);
 
130
#endif
 
131
   speex_free(bank);
 
132
}
 
133
 
 
134
void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel)
 
135
{
 
136
   int i;
 
137
   for (i=0;i<bank->nb_banks;i++)
 
138
      mel[i] = 0;
 
139
 
 
140
   for (i=0;i<bank->len;i++)
 
141
   {
 
142
      int id;
 
143
      id = bank->bank_left[i];
 
144
      mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);
 
145
      id = bank->bank_right[i];
 
146
      mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);
 
147
   }
 
148
   /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
 
149
#ifndef FIXED_POINT
 
150
   /*for (i=0;i<bank->nb_banks;i++)
 
151
      mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]);
 
152
   */
 
153
#endif
 
154
}
 
155
 
 
156
void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps)
 
157
{
 
158
   int i;
 
159
   for (i=0;i<bank->len;i++)
 
160
   {
 
161
      spx_word32_t tmp;
 
162
      int id1, id2;
 
163
      id1 = bank->bank_left[i];
 
164
      id2 = bank->bank_right[i];
 
165
      tmp = MULT16_16(mel[id1],bank->filter_left[i]);
 
166
      tmp += MULT16_16(mel[id2],bank->filter_right[i]);
 
167
      ps[i] = EXTRACT16(PSHR32(tmp,15));
 
168
   }
 
169
}
 
170
 
 
171
 
 
172
#ifndef FIXED_POINT
 
173
void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)
 
174
{
 
175
   int i;
 
176
   for (i=0;i<bank->nb_banks;i++)
 
177
      mel[i] = 0;
 
178
 
 
179
   for (i=0;i<bank->len;i++)
 
180
   {
 
181
      int id = bank->bank_left[i];
 
182
      mel[id] += bank->filter_left[i]*ps[i];
 
183
      id = bank->bank_right[i];
 
184
      mel[id] += bank->filter_right[i]*ps[i];
 
185
   }
 
186
   for (i=0;i<bank->nb_banks;i++)
 
187
      mel[i] *= bank->scaling[i];
 
188
}
 
189
 
 
190
void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)
 
191
{
 
192
   int i;
 
193
   for (i=0;i<bank->len;i++)
 
194
   {
 
195
      int id = bank->bank_left[i];
 
196
      ps[i] = mel[id]*bank->filter_left[i];
 
197
      id = bank->bank_right[i];
 
198
      ps[i] += mel[id]*bank->filter_right[i];
 
199
   }
 
200
}
 
201
 
 
202
void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)
 
203
{
 
204
   /* Low freq slope: 14 dB/Bark*/
 
205
   /* High freq slope: 9 dB/Bark*/
 
206
   /* Noise vs tone: 5 dB difference */
 
207
   /* FIXME: Temporary kludge */
 
208
   float bark[100];
 
209
   int i;
 
210
   /* Assumes 1/3 Bark resolution */
 
211
   float decay_low = 0.34145f;
 
212
   float decay_high = 0.50119f;
 
213
   filterbank_compute_bank(bank, ps, bark);
 
214
   for (i=1;i<bank->nb_banks;i++)
 
215
   {
 
216
      /*float decay_high = 13-1.6*log10(bark[i-1]);
 
217
      decay_high = pow(10,(-decay_high/30.f));*/
 
218
      bark[i] = bark[i] + decay_high*bark[i-1];
 
219
   }
 
220
   for (i=bank->nb_banks-2;i>=0;i--)
 
221
   {
 
222
      bark[i] = bark[i] + decay_low*bark[i+1];
 
223
   }
 
224
   filterbank_compute_psd(bank, bark, mask);
 
225
}
 
226
 
 
227
#endif