Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/src/power_meter.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * power_meter.c | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2003 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: power_meter.c,v 1.31 2009/05/30 17:29:23 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 <float.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 "floating_fudge.h" | |
47 #include <assert.h> | |
48 | |
49 #include "spandsp/telephony.h" | |
50 #include "spandsp/power_meter.h" | |
51 | |
52 SPAN_DECLARE(power_meter_t *) power_meter_init(power_meter_t *s, int shift) | |
53 { | |
54 if (s == NULL) | |
55 { | |
56 if ((s = (power_meter_t *) malloc(sizeof(*s))) == NULL) | |
57 return NULL; | |
58 } | |
59 s->shift = shift; | |
60 s->reading = 0; | |
61 return s; | |
62 } | |
63 /*- End of function --------------------------------------------------------*/ | |
64 | |
65 SPAN_DECLARE(int) power_meter_release(power_meter_t *s) | |
66 { | |
67 return 0; | |
68 } | |
69 /*- End of function --------------------------------------------------------*/ | |
70 | |
71 SPAN_DECLARE(int) power_meter_free(power_meter_t *s) | |
72 { | |
73 if (s) | |
74 free(s); | |
75 return 0; | |
76 } | |
77 /*- End of function --------------------------------------------------------*/ | |
78 | |
79 SPAN_DECLARE(power_meter_t *) power_meter_damping(power_meter_t *s, int shift) | |
80 { | |
81 s->shift = shift; | |
82 return s; | |
83 } | |
84 /*- End of function --------------------------------------------------------*/ | |
85 | |
86 SPAN_DECLARE(int32_t) power_meter_update(power_meter_t *s, int16_t amp) | |
87 { | |
88 s->reading += ((amp*amp - s->reading) >> s->shift); | |
89 return s->reading; | |
90 } | |
91 /*- End of function --------------------------------------------------------*/ | |
92 | |
93 SPAN_DECLARE(int32_t) power_meter_level_dbm0(float level) | |
94 { | |
95 float l; | |
96 | |
97 level -= DBM0_MAX_POWER; | |
98 if (level > 0.0) | |
99 level = 0.0; | |
100 l = powf(10.0f, level/10.0f)*(32767.0f*32767.0f); | |
101 return (int32_t) l; | |
102 } | |
103 /*- End of function --------------------------------------------------------*/ | |
104 | |
105 SPAN_DECLARE(int32_t) power_meter_level_dbov(float level) | |
106 { | |
107 float l; | |
108 | |
109 if (level > 0.0) | |
110 level = 0.0; | |
111 l = powf(10.0f, level/10.0f)*(32767.0f*32767.0f); | |
112 return (int32_t) l; | |
113 } | |
114 /*- End of function --------------------------------------------------------*/ | |
115 | |
116 SPAN_DECLARE(int32_t) power_meter_current(power_meter_t *s) | |
117 { | |
118 return s->reading; | |
119 } | |
120 /*- End of function --------------------------------------------------------*/ | |
121 | |
122 SPAN_DECLARE(float) power_meter_current_dbm0(power_meter_t *s) | |
123 { | |
124 if (s->reading <= 0) | |
125 return -96.329f + DBM0_MAX_POWER; | |
126 /* This is based on A-law, but u-law is only 0.03dB different, so don't worry. */ | |
127 return log10f((float) s->reading/(32767.0f*32767.0f))*10.0f + DBM0_MAX_POWER; | |
128 } | |
129 /*- End of function --------------------------------------------------------*/ | |
130 | |
131 SPAN_DECLARE(float) power_meter_current_dbov(power_meter_t *s) | |
132 { | |
133 if (s->reading <= 0) | |
134 return -96.329f; | |
135 return log10f((float) s->reading/(32767.0f*32767.0f))*10.0f; | |
136 } | |
137 /*- End of function --------------------------------------------------------*/ | |
138 | |
139 SPAN_DECLARE(int32_t) power_surge_detector(power_surge_detector_state_t *s, int16_t amp) | |
140 { | |
141 int32_t pow_short; | |
142 int32_t pow_medium; | |
143 | |
144 pow_short = power_meter_update(&s->short_term, amp); | |
145 pow_medium = power_meter_update(&s->medium_term, amp); | |
146 if (pow_medium < s->min) | |
147 return 0; | |
148 if (!s->signal_present) | |
149 { | |
150 if (pow_short <= s->surge*(pow_medium >> 10)) | |
151 return 0; | |
152 s->signal_present = TRUE; | |
153 s->medium_term.reading = s->short_term.reading; | |
154 } | |
155 else | |
156 { | |
157 if (pow_short < s->sag*(pow_medium >> 10)) | |
158 { | |
159 s->signal_present = FALSE; | |
160 s->medium_term.reading = s->short_term.reading; | |
161 return 0; | |
162 } | |
163 } | |
164 return pow_short; | |
165 } | |
166 /*- End of function --------------------------------------------------------*/ | |
167 | |
168 SPAN_DECLARE(float) power_surge_detector_current_dbm0(power_surge_detector_state_t *s) | |
169 { | |
170 return power_meter_current_dbm0(&s->short_term); | |
171 } | |
172 /*- End of function --------------------------------------------------------*/ | |
173 | |
174 SPAN_DECLARE(float) power_surge_detector_current_dbov(power_surge_detector_state_t *s) | |
175 { | |
176 return power_meter_current_dbov(&s->short_term); | |
177 } | |
178 /*- End of function --------------------------------------------------------*/ | |
179 | |
180 SPAN_DECLARE(power_surge_detector_state_t *) power_surge_detector_init(power_surge_detector_state_t *s, float min, float surge) | |
181 { | |
182 float ratio; | |
183 | |
184 if (s == NULL) | |
185 { | |
186 if ((s = (power_surge_detector_state_t *) malloc(sizeof(*s))) == NULL) | |
187 return NULL; | |
188 } | |
189 memset(s, 0, sizeof(*s)); | |
190 power_meter_init(&s->short_term, 4); | |
191 power_meter_init(&s->medium_term, 7); | |
192 ratio = powf(10.0f, surge/10.0f); | |
193 s->surge = 1024.0f*ratio; | |
194 s->sag = 1024.0f/ratio; | |
195 s->min = power_meter_level_dbm0(min); | |
196 s->medium_term.reading = s->min + 1; | |
197 return s; | |
198 } | |
199 /*- End of function --------------------------------------------------------*/ | |
200 | |
201 SPAN_DECLARE(int) power_surge_detector_release(power_surge_detector_state_t *s) | |
202 { | |
203 return 0; | |
204 } | |
205 /*- End of function --------------------------------------------------------*/ | |
206 | |
207 SPAN_DECLARE(int) power_surge_detector_free(power_surge_detector_state_t *s) | |
208 { | |
209 if (s) | |
210 free(s); | |
211 return 0; | |
212 } | |
213 /*- End of function --------------------------------------------------------*/ | |
214 /*- End of file ------------------------------------------------------------*/ |