comparison spandsp-0.0.6pre17/tests/sig_tone_tests.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 * sig_tone_tests.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.27 2009/09/23 16:02:59 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 <sndfile.h>
46
47 //#if defined(WITH_SPANDSP_INTERNALS)
48 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
49 //#endif
50
51 #include "spandsp.h"
52 #include "spandsp-sim.h"
53
54 #define OUT_FILE_NAME "sig_tone.wav"
55
56 #define SAMPLES_PER_CHUNK 160
57
58 static int sampleno = 0;
59 static int tone_1_present = 0;
60 static int tone_2_present = 0;
61 static int tx_section = 0;
62 static int dial_pulses = 0;
63
64 static void tx_handler(void *user_data, int what, int level, int duration)
65 {
66 sig_tone_tx_state_t *s;
67
68 s = (sig_tone_tx_state_t *) user_data;
69 //printf("What - %d, duration - %d\n", what, duration);
70 if ((what & SIG_TONE_TX_UPDATE_REQUEST))
71 {
72 printf("Tx: update request\n");
73 /* The sig tone transmit side wants to know what to do next */
74 switch (tx_section)
75 {
76 case 0:
77 printf("33ms break - %d samples\n", ms_to_samples(33));
78 tx_section++;
79 sig_tone_tx_set_mode(s, SIG_TONE_1_PRESENT, ms_to_samples(33));
80 break;
81 case 1:
82 printf("67ms make - %d samples\n", ms_to_samples(67));
83 if (++dial_pulses == 9)
84 tx_section++;
85 else
86 tx_section--;
87 sig_tone_tx_set_mode(s, 0, ms_to_samples(67));
88 break;
89 case 2:
90 tx_section++;
91 sig_tone_tx_set_mode(s, SIG_TONE_1_PRESENT, ms_to_samples(600));
92 break;
93 case 3:
94 sig_tone_tx_set_mode(s, SIG_TONE_1_PRESENT | SIG_TONE_TX_PASSTHROUGH, 0);
95 break;
96 }
97 /*endswitch*/
98 }
99 /*endif*/
100 }
101 /*- End of function --------------------------------------------------------*/
102
103 static void rx_handler(void *user_data, int what, int level, int duration)
104 {
105 float ms;
106
107 ms = 1000.0f*(float) duration/(float) SAMPLE_RATE;
108 printf("What - %d, duration - %d\n", what, duration);
109 if ((what & SIG_TONE_1_CHANGE))
110 {
111 tone_1_present = what & SIG_TONE_1_PRESENT;
112 printf("Rx: tone 1 is %s after %d samples (%fms)\n", (tone_1_present) ? "on" : "off", duration, ms);
113 }
114 /*endif*/
115 if ((what & SIG_TONE_2_CHANGE))
116 {
117 tone_2_present = what & SIG_TONE_2_PRESENT;
118 printf("Rx: tone 2 is %s after %d samples (%fms)\n", (tone_2_present) ? "on" : "off", duration, ms);
119 }
120 /*endif*/
121 }
122 /*- End of function --------------------------------------------------------*/
123
124 static void map_frequency_response(sig_tone_rx_state_t *s)
125 {
126 int16_t buf[8192];
127 int i;
128 int len;
129 double sumin;
130 double sumout;
131 swept_tone_state_t *swept;
132
133 /* Things like noise don't highlight the frequency response of the high Q notch
134 very well. We use a slowly swept frequency to check it. */
135 swept = swept_tone_init(NULL, 200.0f, 3900.0f, -10.0f, 120*SAMPLE_RATE, 0);
136 for (;;)
137 {
138 if ((len = swept_tone(swept, buf, SAMPLES_PER_CHUNK)) <= 0)
139 break;
140 sumin = 0.0;
141 for (i = 0; i < len; i++)
142 sumin += (double) buf[i]*(double) buf[i];
143 sig_tone_rx(s, buf, len);
144 sumout = 0.0;
145 for (i = 0; i < len; i++)
146 sumout += (double) buf[i]*(double) buf[i];
147 /*endfor*/
148 printf("%7.1f %f\n", swept_tone_current_frequency(swept), 10.0*log10(sumout/sumin));
149 }
150 /*endfor*/
151 swept_tone_free(swept);
152 }
153 /*- End of function --------------------------------------------------------*/
154
155 int main(int argc, char *argv[])
156 {
157 int16_t amp[SAMPLES_PER_CHUNK];
158 int16_t out_amp[2*SAMPLES_PER_CHUNK];
159 SNDFILE *outhandle;
160 int outframes;
161 int i;
162 int type;
163 int rx_samples;
164 int tx_samples;
165 sig_tone_tx_state_t tx_state;
166 sig_tone_rx_state_t rx_state;
167 awgn_state_t noise_source;
168 codec_munge_state_t *munge;
169
170 if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL)
171 {
172 fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
173 exit(2);
174 }
175 /*endif*/
176
177 awgn_init_dbm0(&noise_source, 1234567, -20.0f);
178
179 for (type = 1; type <= 3; type++)
180 {
181 sampleno = 0;
182 tone_1_present = 0;
183 tone_2_present = 0;
184 tx_section = 0;
185 munge = NULL;
186 switch (type)
187 {
188 case 1:
189 printf("2280Hz tests.\n");
190 munge = codec_munge_init(MUNGE_CODEC_ALAW, 0);
191 sig_tone_tx_init(&tx_state, SIG_TONE_2280HZ, tx_handler, &tx_state);
192 sig_tone_rx_init(&rx_state, SIG_TONE_2280HZ, rx_handler, &rx_state);
193 rx_state.current_rx_tone |= SIG_TONE_RX_PASSTHROUGH;
194 break;
195 case 2:
196 printf("2600Hz tests.\n");
197 munge = codec_munge_init(MUNGE_CODEC_ULAW, 0);
198 sig_tone_tx_init(&tx_state, SIG_TONE_2600HZ, tx_handler, &tx_state);
199 sig_tone_rx_init(&rx_state, SIG_TONE_2600HZ, rx_handler, &rx_state);
200 rx_state.current_rx_tone |= SIG_TONE_RX_PASSTHROUGH;
201 break;
202 case 3:
203 printf("2400Hz/2600Hz tests.\n");
204 munge = codec_munge_init(MUNGE_CODEC_ULAW, 0);
205 sig_tone_tx_init(&tx_state, SIG_TONE_2400HZ_2600HZ, tx_handler, &tx_state);
206 sig_tone_rx_init(&rx_state, SIG_TONE_2400HZ_2600HZ, rx_handler, &rx_state);
207 rx_state.current_rx_tone |= SIG_TONE_RX_PASSTHROUGH;
208 break;
209 }
210 /*endswitch*/
211 /* Set to the default of hook condition */
212 sig_tone_rx_set_mode(&rx_state, SIG_TONE_RX_PASSTHROUGH | SIG_TONE_RX_FILTER_TONE, 0);
213 sig_tone_tx_set_mode(&tx_state, SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT | SIG_TONE_TX_PASSTHROUGH, 0);
214
215 map_frequency_response(&rx_state);
216
217 sig_tone_rx_set_mode(&rx_state, SIG_TONE_RX_PASSTHROUGH, 0);
218 for (sampleno = 0; sampleno < 30000; sampleno += SAMPLES_PER_CHUNK)
219 {
220 if (sampleno == 8000)
221 {
222 /* 100ms seize */
223 printf("100ms seize - %d samples\n", ms_to_samples(100));
224 dial_pulses = 0;
225 sig_tone_tx_set_mode(&tx_state, 0, ms_to_samples(100));
226 }
227 for (i = 0; i < SAMPLES_PER_CHUNK; i++)
228 amp[i] = awgn(&noise_source);
229 /*endfor*/
230 tx_samples = sig_tone_tx(&tx_state, amp, SAMPLES_PER_CHUNK);
231 for (i = 0; i < tx_samples; i++)
232 out_amp[2*i] = amp[i];
233 /*endfor*/
234 codec_munge(munge, amp, tx_samples);
235 rx_samples = sig_tone_rx(&rx_state, amp, tx_samples);
236 for (i = 0; i < rx_samples; i++)
237 out_amp[2*i + 1] = amp[i];
238 /*endfor*/
239 outframes = sf_writef_short(outhandle, out_amp, rx_samples);
240 if (outframes != rx_samples)
241 {
242 fprintf(stderr, " Error writing audio file\n");
243 exit(2);
244 }
245 /*endif*/
246 }
247 /*endfor*/
248 }
249 /*endfor*/
250 if (sf_close(outhandle) != 0)
251 {
252 fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME);
253 exit(2);
254 }
255 /*endif*/
256
257 printf("Tests completed.\n");
258 return 0;
259 }
260 /*- End of function --------------------------------------------------------*/
261 /*- End of file ------------------------------------------------------------*/

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