Bug Summary

File:lpc10_voicing.c
Warning:line 127, column 25
Array access (from variable 'lpbuf') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name lpc10_voicing.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fno-trapping-math -ffp-contract=fast -ffast-math -ffinite-math-only -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-feature +sse2 -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib/llvm-7/lib/clang/7.0.1 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/libxml2 -D NDEBUG -D HAVE_VISIBILITY=1 -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -std=gnu99 -fconst-strings -fdebug-compilation-dir /drone/src/src -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -o /drone/src/scan-build/2021-05-27-190700-749-1 -x c lpc10_voicing.c -faddrsig
1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * lpc10_voicing.c - LPC10 low bit rate speech codec.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2006 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 2.1,
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * This code is based on the U.S. Department of Defense reference
26 * implementation of the LPC-10 2400 bps Voice Coder. They do not
27 * exert copyright claims on their code, and it may be freely used.
28 */
29
30#if defined(HAVE_CONFIG_H1)
31#include "config.h"
32#endif
33
34#include <stdlib.h>
35#include <stdio.h>
36#include <inttypes.h>
37#include <memory.h>
38#if defined(HAVE_TGMATH_H1)
39#include <tgmath.h>
40#endif
41#if defined(HAVE_MATH_H1)
42#include <math.h>
43#endif
44#if defined(HAVE_STDBOOL_H1)
45#include <stdbool.h>
46#else
47#include "spandsp/stdbool.h"
48#endif
49#include "floating_fudge.h"
50
51#include "spandsp/telephony.h"
52#include "spandsp/fast_convert.h"
53#include "spandsp/lpc10.h"
54#include "spandsp/private/lpc10.h"
55
56#include "lpc10_encdecs.h"
57
58static void vparms(int32_t vwin[],
59 float *inbuf,
60 float *lpbuf,
61 const int32_t buflim[],
62 int32_t half,
63 float *dither,
64 int32_t *mintau,
65 int32_t *zc,
66 int32_t *lbe,
67 int32_t *fbe,
68 float *qs,
69 float *rc1,
70 float *ar_b,
71 float *ar_f)
72{
73 int32_t inbuf_offset;
74 int32_t lpbuf_offset;
75 int32_t vlen;
76 int32_t stop;
77 int32_t i;
78 int32_t start;
79 float r1;
80 float r2;
81 float e_pre;
82 float ap_rms;
83 float e_0;
84 float oldsgn;
85 float lp_rms;
86 float e_b;
87 float e_f;
88 float r_b;
89 float r_f;
90 float e0ap;
91
92 /* Calculate zero crossings (ZC) and several energy and correlation */
93 /* measures on low band and full band speech. Each measure is taken */
94 /* over either the first or the second half of the voicing window, */
95 /* depending on the variable HALF. */
96 lpbuf_offset = buflim[2];
8
Value assigned to 'lpbuf_offset'
97 lpbuf -= lpbuf_offset;
9
Null pointer value stored to 'lpbuf'
98 inbuf_offset = buflim[0];
99 inbuf -= inbuf_offset;
100
101 lp_rms = 0.0f;
102 ap_rms = 0.0f;
103 e_pre = 0.0f;
104 e0ap = 0.0f;
105 *rc1 = 0.0f;
106 e_0 = 0.0f;
107 e_b = 0.0f;
108 e_f = 0.0f;
109 r_f = 0.0f;
110 r_b = 0.0f;
111 *zc = 0;
112 vlen = vwin[1] - vwin[0] + 1;
113 start = vwin[0] + half*vlen/2 + 1;
114 stop = start + vlen/2 - 1;
115
116 /* I'll use the symbol HVL in the table below to represent the value */
117 /* VLEN/2. Note that if VLEN is odd, then HVL should be rounded down, */
118 /* i.e., HVL = (VLEN-1)/2. */
119
120 /* HALF START STOP */
121
122 /* 1 VWIN(1)+1 VWIN(1)+HVL */
123 /* 2 VWIN(1)+HVL+1 VWIN(1)+2*HVL */
124 oldsgn = r_sign(1.0f, inbuf[start - 1] - *dither);
125 for (i = start; i <= stop; i++)
10
Assuming 'i' is <= 'stop'
11
Loop condition is true. Entering loop body
126 {
127 lp_rms += fabsf(lpbuf[i]);
12
Array access (from variable 'lpbuf') results in a null pointer dereference
128 ap_rms += fabsf(inbuf[i]);
129 e_pre += fabsf(inbuf[i] - inbuf[i - 1]);
130 r1 = inbuf[i];
131 e0ap += r1*r1;
132 *rc1 += inbuf[i]*inbuf[i - 1];
133 r1 = lpbuf[i];
134 e_0 += r1*r1;
135 r1 = lpbuf[i - *mintau];
136 e_b += r1*r1;
137 r1 = lpbuf[i + *mintau];
138 e_f += r1*r1;
139 r_f += lpbuf[i]*lpbuf[i + *mintau];
140 r_b += lpbuf[i]*lpbuf[i - *mintau];
141 r1 = inbuf[i] + *dither;
142 if (r_sign(1.0f, r1) != oldsgn)
143 {
144 ++(*zc);
145 oldsgn = -oldsgn;
146 }
147 *dither = -(*dither);
148 }
149 /* Normalized short-term autocovariance coefficient at unit sample delay */
150 *rc1 /= max(e0ap, 1.0f)((e0ap) >= (1.0f) ? (e0ap) : (1.0f));
151 /* Ratio of the energy of the first difference signal (6 dB/oct preemphasis)*/
152 /* to the energy of the full band signal */
153 /* Computing MAX */
154 r1 = ap_rms*2.0f;
155 *qs = e_pre/max(r1, 1.0f)((r1) >= (1.0f) ? (r1) : (1.0f));
156 /* aR_b is the product of the forward and reverse prediction gains, */
157 /* looking backward in time (the causal case). */
158 *ar_b = r_b/max(e_b, 1.0f)((e_b) >= (1.0f) ? (e_b) : (1.0f))*(r_b/max(e_0, 1.0f)((e_0) >= (1.0f) ? (e_0) : (1.0f)));
159 /* aR_f is the same as aR_b, but looking forward in time (non causal case).*/
160 *ar_f = r_f/max(e_f, 1.0f)((e_f) >= (1.0f) ? (e_f) : (1.0f))*(r_f/max(e_0, 1.0f)((e_0) >= (1.0f) ? (e_0) : (1.0f)));
161 /* Normalize ZC, LBE, and FBE to old fixed window length of 180. */
162 /* (The fraction 90/VLEN has a range of 0.58 to 1) */
163 r2 = (float) (*zc << 1);
164 *zc = lfastrintf(r2*(90.0f/vlen));
165 r1 = lp_rms/4*(90.0f/vlen);
166 *lbe = min(lfastrintf(r1), 32767)((lfastrintf(r1)) <= (32767) ? (lfastrintf(r1)) : (32767));
167 r1 = ap_rms/4*(90.0f/vlen);
168 *fbe = min(lfastrintf(r1), 32767)((lfastrintf(r1)) <= (32767) ? (lfastrintf(r1)) : (32767));
169}
170/*- End of function --------------------------------------------------------*/
171
172/* Voicing detection makes voicing decisions for each half */
173/* frame of input speech. Tentative voicing decisions are made two frames*/
174/* in the future (2F) for each half frame. These decisions are carried */
175/* through one frame in the future (1F) to the present (P) frame where */
176/* they are examined and smoothed, resulting in the final voicing */
177/* decisions for each half frame. */
178
179/* The voicing parameter (signal measurement) column vector (VALUE) */
180/* is based on a rectangular window of speech samples determined by the */
181/* window placement algorithm. The voicing parameter vector contains the*/
182/* AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy*/
183/* measures, reflection coefficients, and prediction gains. The voicing */
184/* window is placed to avoid contamination of the voicing parameter vector*/
185/* with speech onsets. */
186
187/* The input signal is then classified as unvoiced (including */
188/* silence) or voiced. This decision is made by a linear discriminant */
189/* function consisting of a dot product of the voicing decision */
190/* coefficient (VDC) row vector with the measurement column vector */
191/* (VALUE). The VDC vector is 2-dimensional, each row vector is optimized*/
192/* for a particular signal-to-noise ratio (SNR). So, before the dot */
193/* product is performed, the SNR is estimated to select the appropriate */
194/* VDC vector. */
195
196/* The smoothing algorithm is a modified median smoother. The */
197/* voicing discriminant function is used by the smoother to determine how*/
198/* strongly voiced or unvoiced a signal is. The smoothing is further */
199/* modified if a speech onset and a voicing decision transition occur */
200/* within one half frame. In this case, the voicing decision transition */
201/* is extended to the speech onset. For transmission purposes, there are*/
202/* constraints on the duration and transition of voicing decisions. The */
203/* smoother takes these constraints into account. */
204
205/* Finally, the energy estimates are updated along with the dither */
206/* threshold used to calculate the zero crossing rate (ZC). */
207
208void lpc10_voicing(lpc10_encode_state_t *s,
209 int32_t vwin[],
210 float *inbuf,
211 float *lpbuf,
212 const int32_t buflim[],
213 int32_t half,
214 float *minamd,
215 float *maxamd,
216 int32_t *mintau,
217 float ivrc[],
218 int32_t obound[])
219{
220 static const float vdc[100] =
221 {
222 0.0f, 1714.0f, -110.0f, 334.0f, -4096.0f, -654.0f, 3752.0f, 3769.0f, 0.0f, 1181.0f,
223 0.0f, 874.0f, -97.0f, 300.0f, -4096.0f, -1021.0f, 2451.0f, 2527.0f, 0.0f, -500.0f,
224 0.0f, 510.0f, -70.0f, 250.0f, -4096.0f, -1270.0f, 2194.0f, 2491.0f, 0.0f, -1500.0f,
225 0.0f, 500.0f, -10.0f, 200.0f, -4096.0f, -1300.0f, 2.0e3f, 2.0e3f, 0.0f, -2.0e3f,
226 0.0f, 500.0f, 0.0f, 0.0f, -4096.0f, -1300.0f, 2.0e3f, 2.0e3f, 0.0f, -2500.0f,
227 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
228 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
229 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
230 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
231 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
232 };
233 static const int nvdcl = 5;
234 static const float vdcl[10] =
235 {
236 600.0f, 450.0f, 300.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
237 };
238
239 int32_t inbuf_offset;
240 int32_t lpbuf_offset;
241 int32_t i1;
242 float r1;
243 float r2;
244 float ar_b;
245 float ar_f;
246 int32_t snrl;
247 int32_t i;
248 float value[9];
249 int32_t zc;
250 int ot;
251 float qs;
252 int32_t vstate;
253 float rc1;
254 int32_t fbe;
255 int32_t lbe;
256 float snr2;
257
258#if (_MSC_VER >= 1400)
259 __analysis_assume(half >= 0 && half < 2);
260#endif
261 inbuf_offset = 0;
262 lpbuf_offset = 0;
263 if (inbuf)
1
Assuming 'inbuf' is non-null
2
Taking true branch
264 {
265 inbuf_offset = buflim[0];
266 inbuf -= inbuf_offset;
267 }
268 if (lpbuf)
3
Assuming 'lpbuf' is null
4
Taking false branch
269 {
270 lpbuf_offset = buflim[2];
271 lpbuf -= lpbuf_offset;
272 }
273
274 /* Voicing Decision Parameter vector (* denotes zero coefficient): */
275
276 /* * MAXMIN */
277 /* LBE/LBVE */
278 /* ZC */
279 /* RC1 */
280 /* QS */
281 /* IVRC2 */
282 /* aR_B */
283 /* aR_F */
284 /* * LOG(LBE/LBVE) */
285 /* Define 2-D voicing decision coefficient vector according to the voicing */
286 /* parameter order above. Each row (VDC vector) is optimized for a specific */
287 /* SNR. The last element of the vector is the constant. */
288 /* E ZC RC1 Qs IVRC2 aRb aRf c */
289
290 /* The VOICE array contains the result of the linear discriminant function*/
291 /* (analog values). The VOIBUF array contains the hard-limited binary */
292 /* voicing decisions. The VOICE and VOIBUF arrays, according to FORTRAN */
293 /* memory allocation, are addressed as: */
294
295 /* (half-frame number, future-frame number) */
296
297 /* | Past | Present | Future1 | Future2 | */
298 /* | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 | ---> time */
299
300 /* Update linear discriminant function history each frame: */
301 if (half == 0)
5
Assuming 'half' is not equal to 0
6
Taking false branch
302 {
303 s->voice[0][0] = s->voice[1][0];
304 s->voice[0][1] = s->voice[1][1];
305 s->voice[1][0] = s->voice[2][0];
306 s->voice[1][1] = s->voice[2][1];
307 s->maxmin = *maxamd / max(*minamd, 1.0f)((*minamd) >= (1.0f) ? (*minamd) : (1.0f));
308 }
309 /* Calculate voicing parameters twice per frame */
310 vparms(vwin,
7
Calling 'vparms'
311 &inbuf[inbuf_offset],
312 &lpbuf[lpbuf_offset],
313 buflim,
314 half,
315 &s->dither,
316 mintau,
317 &zc,
318 &lbe,
319 &fbe,
320 &qs,
321 &rc1,
322 &ar_b,
323 &ar_f);
324 /* Estimate signal-to-noise ratio to select the appropriate VDC vector. */
325 /* The SNR is estimated as the running average of the ratio of the */
326 /* running average full-band voiced energy to the running average */
327 /* full-band unvoiced energy. SNR filter has gain of 63. */
328 r1 = (s->snr + s->fbve/(float) max(s->fbue, 1)((s->fbue) >= (1) ? (s->fbue) : (1)))*63/64.0f;
329 s->snr = (float) lfastrintf(r1);
330 snr2 = s->snr*s->fbue/max(s->lbue, 1)((s->lbue) >= (1) ? (s->lbue) : (1));
331 /* Quantize SNR to SNRL according to VDCL thresholds. */
332 i1 = nvdcl - 1;
333 for (snrl = 0; snrl < i1; snrl++)
334 {
335 if (snr2 > vdcl[snrl])
336 break;
337 }
338 /* (Note: SNRL = NVDCL here) */
339 /* Linear discriminant voicing parameters: */
340 value[0] = s->maxmin;
341 value[1] = (float) lbe/max(s->lbve, 1)((s->lbve) >= (1) ? (s->lbve) : (1));
342 value[2] = (float) zc;
343 value[3] = rc1;
344 value[4] = qs;
345 value[5] = ivrc[1];
346 value[6] = ar_b;
347 value[7] = ar_f;
348 /* Evaluation of linear discriminant function: */
349 s->voice[2][half] = vdc[snrl*10 + 9];
350 for (i = 0; i < 8; i++)
351 s->voice[2][half] += vdc[snrl*10 + i]*value[i];
352 /* Classify as voiced if discriminant > 0, otherwise unvoiced */
353 /* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */
354 s->voibuf[3][half] = (s->voice[2][half] > 0.0f) ? 1 : 0;
355 /* Skip voicing decision smoothing in first half-frame: */
356 if (half != 0)
357 {
358 /* Voicing decision smoothing rules (override of linear combination): */
359
360 /* Unvoiced half-frames: At least two in a row. */
361 /* -------------------- */
362
363 /* Voiced half-frames: At least two in a row in one frame. */
364 /* ------------------- Otherwise at least three in a row. */
365 /* (Due to the way transition frames are encoded) */
366
367 /* In many cases, the discriminant function determines how to smooth. */
368 /* In the following chart, the decisions marked with a * may be overridden. */
369
370 /* Voicing override of transitions at onsets: */
371 /* If a V/UV or UV/V voicing decision transition occurs within one-half */
372 /* frame of an onset bounding a voicing window, then the transition is */
373 /* moved to occur at the onset. */
374
375 /* P 1F */
376 /* ----- ----- */
377 /* 0 0 0 0 */
378 /* 0 0 0* 1 (If there is an onset there) */
379 /* 0 0 1* 0* (Based on 2F and discriminant distance) */
380 /* 0 0 1 1 */
381 /* 0 1* 0 0 (Always) */
382 /* 0 1* 0* 1 (Based on discriminant distance) */
383 /* 0* 1 1 0* (Based on past, 2F, and discriminant distance) */
384 /* 0 1* 1 1 (If there is an onset there) */
385 /* 1 0* 0 0 (If there is an onset there) */
386 /* 1 0 0 1 */
387 /* 1 0* 1* 0 (Based on discriminant distance) */
388 /* 1 0* 1 1 (Always) */
389 /* 1 1 0 0 */
390 /* 1 1 0* 1* (Based on 2F and discriminant distance) */
391 /* 1 1 1* 0 (If there is an onset there) */
392 /* 1 1 1 1 */
393
394 /* Determine if there is an onset transition between P and 1F. */
395 /* OT (Onset Transition) is true if there is an onset between */
396 /* P and 1F but not after 1F. */
397 ot = ((obound[0] & 2) != 0 || obound[1] == 1) && (obound[2] & 1) == 0;
398 /* Multi-way dispatch on voicing decision history: */
399 vstate = (s->voibuf[1][0] << 3) + (s->voibuf[1][1] << 2) + (s->voibuf[2][0] << 1) + s->voibuf[2][1];
400 switch (vstate + 1)
401 {
402 case 2:
403 if (ot && s->voibuf[3][0] == 1)
404 s->voibuf[2][0] = 1;
405 break;
406 case 3:
407 if (s->voibuf[3][0] == 0 || s->voice[1][0] < -s->voice[1][1])
408 s->voibuf[2][0] = 0;
409 else
410 s->voibuf[2][1] = 1;
411 break;
412 case 5:
413 s->voibuf[1][1] = 0;
414 break;
415 case 6:
416 if (s->voice[0][1] < -s->voice[1][0])
417 s->voibuf[1][1] = 0;
418 else
419 s->voibuf[2][0] = 1;
420 break;
421 case 7:
422 if (s->voibuf[0][0] == 1 || s->voibuf[3][0] == 1 || s->voice[1][1] > s->voice[0][0])
423 s->voibuf[2][1] = 1;
424 else
425 s->voibuf[1][0] = 1;
426 break;
427 case 8:
428 if (ot)
429 s->voibuf[1][1] = 0;
430 break;
431 case 9:
432 if (ot)
433 s->voibuf[1][1] = 1;
434 break;
435 case 11:
436 if (s->voice[1][0] < -s->voice[0][1])
437 s->voibuf[2][0] = 0;
438 else
439 s->voibuf[1][1] = 1;
440 break;
441 case 12:
442 s->voibuf[1][1] = 1;
443 break;
444 case 14:
445 if (s->voibuf[3][0] == 0 && s->voice[1][1] < -s->voice[1][0])
446 s->voibuf[2][1] = 0;
447 else
448 s->voibuf[2][0] = 1;
449 break;
450 case 15:
451 if (ot && s->voibuf[3][0] == 0)
452 s->voibuf[2][0] = 0;
453 break;
454 }
455 }
456 /* During unvoiced half-frames, update the low band and full band unvoiced*/
457 /* energy estimates (LBUE and FBUE) and also the zero crossing */
458 /* threshold (DITHER). (The input to the unvoiced energy filters is */
459 /* restricted to be less than 10dB above the previous inputs of the */
460 /* filters.) */
461 /* During voiced half-frames, update the low-pass (LBVE) and all-pass */
462 /* (FBVE) voiced energy estimates. */
463 if (s->voibuf[3][half] == 0)
464 {
465 r1 = (s->sfbue*63 + (min(fbe, s->ofbue*3)((fbe) <= (s->ofbue*3) ? (fbe) : (s->ofbue*3)) << 3))/64.0f;
466 s->sfbue = lfastrintf(r1);
467 s->fbue = s->sfbue/8;
468 s->ofbue = fbe;
469 r1 = (s->slbue*63 + (min(lbe, s->olbue*3)((lbe) <= (s->olbue*3) ? (lbe) : (s->olbue*3)) << 3))/64.0f;
470 s->slbue = lfastrintf(r1);
471 s->lbue = s->slbue/8;
472 s->olbue = lbe;
473 }
474 else
475 {
476 s->lbve = lfastrintf((s->lbve*63 + lbe)/64.0f);
477 s->fbve = lfastrintf((s->fbve*63 + fbe)/64.0f);
478 }
479 /* Set dither threshold to yield proper zero crossing rates in the */
480 /* presence of low frequency noise and low level signal input. */
481 /* NOTE: The divisor is a function of REF, the expected energies. */
482 /* Computing MIN */
483 /* Computing MAX */
484 r2 = sqrtf((float) (s->lbue*s->lbve))*64/3000;
485 r1 = max(r2, 1.0f)((r2) >= (1.0f) ? (r2) : (1.0f));
486 s->dither = min(r1, 20.0f)((r1) <= (20.0f) ? (r1) : (20.0f));
487 /* Voicing decisions are returned in VOIBUF. */
488}
489/*- End of function --------------------------------------------------------*/
490/*- End of file ------------------------------------------------------------*/