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