Mercurial > hg > audiostuff
comparison spandsp-0.0.3/spandsp-0.0.3/src/tone_generate.c @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:26cd8f1ef0b1 | 5:f762bf195c4b |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * tone_generate.c - General telephony tone generation, and specific | |
5 * generation of Bell MF, MFC/R2, and network supervisory tones. | |
6 * | |
7 * Written by Steve Underwood <steveu@coppice.org> | |
8 * | |
9 * Copyright (C) 2001 Steve Underwood | |
10 * | |
11 * All rights reserved. | |
12 * | |
13 * This program is free software; you can redistribute it and/or modify | |
14 * it under the terms of the GNU General Public License version 2, as | |
15 * published by the Free Software Foundation. | |
16 * | |
17 * This program is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 * GNU General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU General Public License | |
23 * along with this program; if not, write to the Free Software | |
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 * | |
26 * $Id: tone_generate.c,v 1.31 2006/11/28 16:59:56 steveu Exp $ | |
27 */ | |
28 | |
29 /*! \file */ | |
30 | |
31 #ifdef HAVE_CONFIG_H | |
32 #include "config.h" | |
33 #endif | |
34 | |
35 #include <inttypes.h> | |
36 #include <string.h> | |
37 #include <stdlib.h> | |
38 #include <stdio.h> | |
39 #include <time.h> | |
40 #include <fcntl.h> | |
41 #if defined(HAVE_TGMATH_H) | |
42 #include <tgmath.h> | |
43 #endif | |
44 #if defined(HAVE_MATH_H) | |
45 #include <math.h> | |
46 #endif | |
47 | |
48 #include "spandsp/telephony.h" | |
49 #include "spandsp/dc_restore.h" | |
50 #include "spandsp/dds.h" | |
51 #include "spandsp/tone_generate.h" | |
52 | |
53 #if !defined(M_PI) | |
54 /* C99 systems may not define M_PI */ | |
55 #define M_PI 3.14159265358979323846264338327 | |
56 #endif | |
57 | |
58 #define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000) | |
59 | |
60 void make_tone_gen_descriptor(tone_gen_descriptor_t *s, | |
61 int f1, | |
62 int l1, | |
63 int f2, | |
64 int l2, | |
65 int d1, | |
66 int d2, | |
67 int d3, | |
68 int d4, | |
69 int repeat) | |
70 { | |
71 memset(s, 0, sizeof(*s)); | |
72 if (f1 >= 1) | |
73 { | |
74 s->phase_rate[0] = dds_phase_ratef((float) f1); | |
75 s->gain[0] = dds_scaling_dbm0f((float) l1); | |
76 } | |
77 s->modulate = (f2 < 0); | |
78 if (f2) | |
79 { | |
80 s->phase_rate[1] = dds_phase_ratef((float) abs(f2)); | |
81 s->gain[1] = (s->modulate) ? (float) l2/100.0f : dds_scaling_dbm0f((float) l2); | |
82 } | |
83 | |
84 s->duration[0] = d1*8; | |
85 s->duration[1] = d2*8; | |
86 s->duration[2] = d3*8; | |
87 s->duration[3] = d4*8; | |
88 | |
89 s->repeat = repeat; | |
90 } | |
91 /*- End of function --------------------------------------------------------*/ | |
92 | |
93 void make_tone_descriptor(tone_gen_descriptor_t *desc, cadenced_tone_t *tone) | |
94 { | |
95 make_tone_gen_descriptor(desc, | |
96 tone->f1, | |
97 tone->level1, | |
98 tone->f2, | |
99 tone->level2, | |
100 tone->on_time1, | |
101 tone->off_time1, | |
102 tone->on_time2, | |
103 tone->off_time2, | |
104 tone->repeat); | |
105 } | |
106 /*- End of function --------------------------------------------------------*/ | |
107 | |
108 void tone_gen_init(tone_gen_state_t *s, tone_gen_descriptor_t *t) | |
109 { | |
110 int i; | |
111 | |
112 s->phase_rate[0] = t->phase_rate[0]; | |
113 s->gain[0] = t->gain[0]; | |
114 s->phase_rate[1] = t->phase_rate[1]; | |
115 s->gain[1] = t->gain[1]; | |
116 s->modulate = t->modulate; | |
117 | |
118 for (i = 0; i < 4; i++) | |
119 s->duration[i] = t->duration[i]; | |
120 s->repeat = t->repeat; | |
121 | |
122 s->phase[0] = 0; | |
123 s->phase[1] = 0; | |
124 | |
125 s->current_section = 0; | |
126 s->current_position = 0; | |
127 } | |
128 /*- End of function --------------------------------------------------------*/ | |
129 | |
130 int tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples) | |
131 { | |
132 int samples; | |
133 int limit; | |
134 float xamp; | |
135 float yamp; | |
136 | |
137 if (s->current_section < 0) | |
138 return 0; | |
139 | |
140 for (samples = 0; samples < max_samples; ) | |
141 { | |
142 limit = samples + s->duration[s->current_section] - s->current_position; | |
143 if (limit > max_samples) | |
144 limit = max_samples; | |
145 | |
146 s->current_position += (limit - samples); | |
147 if (s->current_section & 1) | |
148 { | |
149 /* A silent section */ | |
150 for ( ; samples < limit; samples++) | |
151 amp[samples] = 0; | |
152 } | |
153 else | |
154 { | |
155 for ( ; samples < limit; samples++) | |
156 { | |
157 xamp = 0.0; | |
158 if (s->phase_rate[0]) | |
159 xamp = dds_modf(&(s->phase[0]), s->phase_rate[0], s->gain[0], 0); | |
160 if (s->phase_rate[1]) | |
161 { | |
162 yamp = dds_modf(&(s->phase[1]), s->phase_rate[1], s->gain[1], 0); | |
163 if (s->modulate) | |
164 xamp *= (1.0f + yamp); | |
165 else | |
166 xamp += yamp; | |
167 } | |
168 /* Saturation of the answer is the right thing at this point. | |
169 However, we are normally generating well controlled tones, | |
170 that cannot clip. So, the overhead of doing saturation is | |
171 a waste of valuable time. */ | |
172 amp[samples] = (int16_t) lrintf(xamp); | |
173 } | |
174 } | |
175 if (s->current_position >= s->duration[s->current_section]) | |
176 { | |
177 s->current_position = 0; | |
178 if (++s->current_section > 3 || s->duration[s->current_section] == 0) | |
179 { | |
180 if (!s->repeat) | |
181 { | |
182 /* Force a quick exit */ | |
183 s->current_section = -1; | |
184 break; | |
185 } | |
186 s->current_section = 0; | |
187 } | |
188 } | |
189 } | |
190 return samples; | |
191 } | |
192 /*- End of function --------------------------------------------------------*/ | |
193 /*- End of file ------------------------------------------------------------*/ |