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 ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.