1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * silence_gen.c - A silence generator, for inserting timed silences.
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 * $Id: silence_gen.c,v 1.13 2008/07/16 18:09:59 steveu Exp $
26 */
27
28 /*! \file */
29
30 #if defined(HAVE_CONFIG_H)
31 #include "config.h"
32 #endif
33
34 #include <inttypes.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <fcntl.h>
38 #include <string.h>
39 #include "floating_fudge.h"
40 #if defined(HAVE_TGMATH_H)
41 #include <tgmath.h>
42 #endif
43 #if defined(HAVE_MATH_H)
44 #include <math.h>
45 #endif
46 #include <assert.h>
47 #include <limits.h>
48
49 #include "spandsp/telephony.h"
50 #include "spandsp/logging.h"
51 #include "spandsp/async.h"
52 #include "spandsp/silence_gen.h"
53
silence_gen(silence_gen_state_t * s,int16_t * amp,int max_len)54 int silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len)
55 {
56 if (s->remaining_samples != INT_MAX)
57 {
58 if (max_len >= s->remaining_samples)
59 {
60 max_len = s->remaining_samples;
61 if (max_len && s->status_handler)
62 s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE);
63 }
64 s->remaining_samples -= max_len;
65 }
66 if (INT_MAX - s->total_samples >= max_len)
67 s->total_samples += max_len;
68 memset(amp, 0, max_len*sizeof(int16_t));
69 return max_len;
70 }
71 /*- End of function --------------------------------------------------------*/
72
silence_gen_always(silence_gen_state_t * s)73 void silence_gen_always(silence_gen_state_t *s)
74 {
75 s->remaining_samples = INT_MAX;
76 }
77 /*- End of function --------------------------------------------------------*/
78
silence_gen_set(silence_gen_state_t * s,int silent_samples)79 void silence_gen_set(silence_gen_state_t *s, int silent_samples)
80 {
81 s->remaining_samples = silent_samples;
82 s->total_samples = 0;
83 }
84 /*- End of function --------------------------------------------------------*/
85
silence_gen_alter(silence_gen_state_t * s,int silent_samples)86 void silence_gen_alter(silence_gen_state_t *s, int silent_samples)
87 {
88 /* Block negative silences */
89 if (silent_samples < 0)
90 {
91 if (-silent_samples > s->remaining_samples)
92 silent_samples = -s->remaining_samples;
93 }
94 s->remaining_samples += silent_samples;
95 s->total_samples += silent_samples;
96 }
97 /*- End of function --------------------------------------------------------*/
98
silence_gen_remainder(silence_gen_state_t * s)99 int silence_gen_remainder(silence_gen_state_t *s)
100 {
101 return s->remaining_samples;
102 }
103 /*- End of function --------------------------------------------------------*/
104
silence_gen_generated(silence_gen_state_t * s)105 int silence_gen_generated(silence_gen_state_t *s)
106 {
107 return s->total_samples;
108 }
109 /*- End of function --------------------------------------------------------*/
110
silence_gen_status_handler(silence_gen_state_t * s,modem_tx_status_func_t handler,void * user_data)111 void silence_gen_status_handler(silence_gen_state_t *s, modem_tx_status_func_t handler, void *user_data)
112 {
113 s->status_handler = handler;
114 s->status_user_data = user_data;
115 }
116 /*- End of function --------------------------------------------------------*/
117
silence_gen_init(silence_gen_state_t * s,int silent_samples)118 silence_gen_state_t *silence_gen_init(silence_gen_state_t *s, int silent_samples)
119 {
120 if (s == NULL)
121 {
122 if ((s = (silence_gen_state_t *) malloc(sizeof(*s))) == NULL)
123 return NULL;
124 }
125 memset(s, 0, sizeof(*s));
126 s->remaining_samples = silent_samples;
127 return s;
128 }
129 /*- End of function --------------------------------------------------------*/
130 /*- End of file ------------------------------------------------------------*/
131