1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * test_sig_tone.c
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2004 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 General Public License version 2, as
14 * 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 General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: sig_tone_tests.c,v 1.20 2008/05/13 13:17:26 steveu Exp $
26 */
27
28 /*! \file */
29
30 /*! \page sig_tone_tests_page The signaling tone processor tests
31 \section sig_tone_tests_sec_1 What does it do?
32 ???.
33
34 \section sig_tone_tests_sec_2 How does it work?
35 ???.
36 */
37
38 #if defined(HAVE_CONFIG_H)
39 #include "config.h"
40 #endif
41
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <memory.h>
45 #include <audiofile.h>
46
47 #include "spandsp.h"
48
49 #define OUT_FILE_NAME "sig_tone.wav"
50
51 static int sampleno = 0;
52 static int tone_1_present = 0;
53 static int tone_2_present = 0;
54 static int ping = 0;
55
56 void map_frequency_response(sig_tone_state_t *s);
57
handler(void * user_data,int what)58 static int handler(void *user_data, int what)
59 {
60 //printf("What - %d\n", what);
61 if ((what & SIG_TONE_1_CHANGE))
62 {
63 tone_1_present = what & SIG_TONE_1_PRESENT;
64 printf("Tone 1 is %s after %d samples\n", (tone_1_present) ? "on" : "off", (what >> 16) & 0xFFFF);
65 }
66 /*endif*/
67 if ((what & SIG_TONE_2_CHANGE))
68 {
69 tone_2_present = what & SIG_TONE_2_PRESENT;
70 printf("Tone 2 is %s after %d samples\n", (tone_2_present) ? "on" : "off", (what >> 16) & 0xFFFF);
71 }
72 /*endif*/
73 if ((what & SIG_TONE_UPDATE_REQUEST))
74 {
75 /* The signaling processor wants to know what to do next */
76 if (sampleno < 800)
77 {
78 /* 100ms off-hook */
79 printf("100ms off-hook - %d samples\n", 800 - sampleno);
80 return 0x02 | ((800 - sampleno) << 16) | SIG_TONE_RX_PASSTHROUGH;
81 }
82 /*endif*/
83 if (sampleno < 4800)
84 {
85 /* 500ms idle */
86 printf("500ms idle - %d samples\n", 4800 - sampleno);
87 return 0x02 | SIG_TONE_1_PRESENT | ((4800 - sampleno) << 16) | SIG_TONE_RX_PASSTHROUGH;
88 }
89 /*endif*/
90 if (sampleno < 5600)
91 {
92 /* 100ms seize */
93 printf("100ms seize - %d samples\n", 5600 - sampleno);
94 return 0x02 | ((5600 - sampleno) << 16) | SIG_TONE_RX_PASSTHROUGH;
95 }
96 /*endif*/
97 if (ping)
98 {
99 printf("33ms break - 262 samples\n");
100 ping = !ping;
101 return 0x02 | (262 << 16) | SIG_TONE_RX_PASSTHROUGH;
102 }
103 else
104 {
105 printf("67ms make - 528 samples\n");
106 ping = !ping;
107 return 0x02 | SIG_TONE_1_PRESENT | (528 << 16) | SIG_TONE_RX_PASSTHROUGH;
108 }
109 /*endif*/
110 }
111 /*endif*/
112 return 0;
113 }
114 /*- End of function --------------------------------------------------------*/
115
map_frequency_response(sig_tone_state_t * s)116 void map_frequency_response(sig_tone_state_t *s)
117 {
118 int16_t buf[8192];
119 awgn_state_t noise_source;
120 int i;
121 int f;
122 uint32_t phase_acc;
123 int32_t phase_rate;
124 int32_t scaling;
125 double sum;
126
127 /* Things like noise don't highlight the frequency response of the high Q notch
128 very well. We use a slowly swept frequency to check it. */
129 awgn_init_dbm0(&noise_source, 1234567, -10.0f);
130 for (f = 1; f < 4000; f++)
131 {
132 phase_rate = dds_phase_rate(f);
133 scaling = dds_scaling_dbm0(-10);
134 phase_acc = 0;
135 for (i = 0; i < 8192; i++)
136 buf[i] = dds_mod(&phase_acc, phase_rate, scaling, 0);
137 /*endfor*/
138 sig_tone_rx(s, buf, 8192);
139 sum = 0.0;
140 for (i = 1000; i < 8192; i++)
141 sum += (double) buf[i]*(double) buf[i];
142 /*endfor*/
143 sum = sqrt(sum);
144 printf("%7d %f\n", f, sum);
145 }
146 /*endfor*/
147 }
148 /*- End of function --------------------------------------------------------*/
149
main(int argc,char * argv[])150 int main(int argc, char *argv[])
151 {
152 int16_t amp[160];
153 int16_t out_amp[2*160];
154 AFfilehandle outhandle;
155 AFfilesetup filesetup;
156 int outframes;
157 int i;
158 int rx_samples;
159 int tx_samples;
160 sig_tone_state_t state;
161 awgn_state_t noise_source;
162
163 filesetup = afNewFileSetup();
164 if (filesetup == AF_NULL_FILESETUP)
165 {
166 fprintf(stderr, " Failed to create file setup\n");
167 exit(2);
168 }
169 /*endif*/
170 afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
171 afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
172 afInitFileFormat(filesetup, AF_FILE_WAVE);
173 afInitChannels(filesetup, AF_DEFAULT_TRACK, 2);
174
175 outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup);
176 if (outhandle == AF_NULL_FILEHANDLE)
177 {
178 fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME);
179 exit(2);
180 }
181 /*endif*/
182
183 awgn_init_dbm0(&noise_source, 1234567, -30.0f);
184
185 printf("2400Hz/26000Hz tests.\n");
186 sig_tone_init(&state, SIG_TONE_2400HZ_2600HZ, handler, NULL);
187 state.current_tx_tone |= SIG_TONE_RX_PASSTHROUGH;
188
189 map_frequency_response(&state);
190
191 for (sampleno = 0; sampleno < 20000; sampleno += 160)
192 {
193 tx_samples = 160;
194 for (i = 0; i < tx_samples; i++)
195 amp[i] = alaw_to_linear(linear_to_alaw(awgn(&noise_source)));
196 /*endfor*/
197 for (i = 0; i < tx_samples; i++)
198 out_amp[2*i] = amp[i];
199 /*endfor*/
200 rx_samples = sig_tone_rx(&state, amp, tx_samples);
201 for (i = 0; i < rx_samples; i++)
202 out_amp[2*i + 1] = amp[i];
203 /*endfor*/
204 outframes = afWriteFrames(outhandle,
205 AF_DEFAULT_TRACK,
206 out_amp,
207 rx_samples);
208 if (outframes != rx_samples)
209 {
210 fprintf(stderr, " Error writing wave file\n");
211 exit(2);
212 }
213 /*endif*/
214 }
215
216 printf("2280Hz tests.\n");
217 sig_tone_init(&state, SIG_TONE_2280HZ, handler, NULL);
218 state.current_tx_tone |= SIG_TONE_RX_PASSTHROUGH;
219
220 map_frequency_response(&state);
221
222 for (sampleno = 0; sampleno < 20000; sampleno += 160)
223 {
224 memset(amp, 0, sizeof(int16_t)*160);
225 tx_samples = sig_tone_tx(&state, amp, 160);
226 for (i = 0; i < tx_samples; i++)
227 out_amp[2*i] = amp[i];
228 /*endfor*/
229 rx_samples = sig_tone_rx(&state, amp, tx_samples);
230 for (i = 0; i < rx_samples; i++)
231 out_amp[2*i + 1] = amp[i];
232 /*endfor*/
233 outframes = afWriteFrames(outhandle,
234 AF_DEFAULT_TRACK,
235 out_amp,
236 rx_samples);
237 if (outframes != rx_samples)
238 {
239 fprintf(stderr, " Error writing wave file\n");
240 exit(2);
241 }
242 /*endif*/
243 }
244 /*endfor*/
245 if (afCloseFile(outhandle) != 0)
246 {
247 fprintf(stderr, " Cannot close wave file '%s'\n", OUT_FILE_NAME);
248 exit(2);
249 }
250 /*endif*/
251 afFreeFileSetup(filesetup);
252
253 printf("Tests completed.\n");
254 return 0;
255 }
256 /*- End of function --------------------------------------------------------*/
257 /*- End of file ------------------------------------------------------------*/
258