comparison spandsp-0.0.6pre17/tests/make_g168_css.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 * makecss.c - Create the composite source signal (CSS) for G.168 testing.
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 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: make_g168_css.c,v 1.18 2009/05/30 15:23:14 steveu Exp $
26 */
27
28 /*! \page makecss_page CSS construction for G.168 testing
29 \section makecss_page_sec_1 What does it do?
30 ???.
31
32 \section makecss_page_sec_2 How does it work?
33 ???.
34 */
35
36 #if defined(HAVE_CONFIG_H)
37 #include "config.h"
38 #endif
39
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <time.h>
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <sndfile.h>
47 #if defined(HAVE_FFTW3_H)
48 #include <fftw3.h>
49 #else
50 #include <fftw.h>
51 #endif
52
53 //#if defined(WITH_SPANDSP_INTERNALS)
54 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
55 //#endif
56
57 #include "spandsp.h"
58 #include "spandsp/g168models.h"
59
60 #if !defined(NULL)
61 #define NULL (void *) 0
62 #endif
63
64 #define FAST_SAMPLE_RATE 44100.0
65
66 #define C1_VOICED_SAMPLES 2144 /* 48.62ms at 44100 samples/second => 2144.142 */
67 #define C1_NOISE_SAMPLES 8820 /* 200ms at 44100 samples/second => 8820.0 */
68 #define C1_SILENCE_SAMPLES 4471 /* 101.38ms at 44100 samples/second => 4470.858 */
69
70 #define C3_VOICED_SAMPLES 3206 /* 72.69ms at 44100 samples/second => 3205.629 */
71 #define C3_NOISE_SAMPLES 8820 /* 200ms at 44100 samples/second => 8820.0 */
72 #define C3_SILENCE_SAMPLES 5614 /* 127.31ms at 44100 samples/second => 5614.371 */
73
74 static double scaling(double f, double start, double end, double start_gain, double end_gain)
75 {
76 double scale;
77
78 scale = start_gain + (f - start)*(end_gain - start_gain)/(end - start);
79 return scale;
80 }
81 /*- End of function --------------------------------------------------------*/
82
83 static double peak(const int16_t amp[], int len)
84 {
85 int16_t peak;
86 int i;
87
88 peak = 0;
89 for (i = 0; i < len; i++)
90 {
91 if (abs(amp[i]) > peak)
92 peak = abs(amp[i]);
93 }
94 return peak/32767.0;
95 }
96 /*- End of function --------------------------------------------------------*/
97
98 static double rms(const int16_t amp[], int len)
99 {
100 double ms;
101 int i;
102
103 ms = 0.0;
104 for (i = 0; i < len; i++)
105 ms += amp[i]*amp[i];
106 return sqrt(ms/len)/32767.0;
107 }
108 /*- End of function --------------------------------------------------------*/
109
110 static double rms_to_dbm0(double rms)
111 {
112 return 20.0*log10(rms) + DBM0_MAX_POWER;
113 }
114 /*- End of function --------------------------------------------------------*/
115
116 static double rms_to_db(double rms)
117 {
118 return 20.0*log10(rms);
119 }
120 /*- End of function --------------------------------------------------------*/
121
122 int main(int argc, char *argv[])
123 {
124 #if defined(HAVE_FFTW3_H)
125 double in[8192][2];
126 double out[8192][2];
127 #else
128 fftw_complex in[8192];
129 fftw_complex out[8192];
130 #endif
131 fftw_plan p;
132 int16_t voiced_sound[8192];
133 int16_t noise_sound[8830];
134 int16_t silence_sound[8192];
135 int i;
136 int outframes;
137 int voiced_length;
138 double f;
139 double pk;
140 double ms;
141 double scale;
142 SNDFILE *filehandle;
143 SF_INFO info;
144 awgn_state_t noise_source;
145
146 memset(&info, 0, sizeof(info));
147 info.frames = 0;
148 info.samplerate = FAST_SAMPLE_RATE;
149 info.channels = 1;
150 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
151 info.sections = 1;
152 info.seekable = 1;
153 if ((filehandle = sf_open("sound_c1.wav", SFM_WRITE, &info)) == NULL)
154 {
155 fprintf(stderr, " Failed to open result file\n");
156 exit(2);
157 }
158
159 printf("Generate C1\n");
160 /* The set of C1 voice samples is ready for use in the output file. */
161 voiced_length = sizeof(css_c1)/sizeof(css_c1[0]);
162 for (i = 0; i < voiced_length; i++)
163 voiced_sound[i] = css_c1[i];
164 pk = peak(voiced_sound, voiced_length);
165 ms = rms(voiced_sound, voiced_length);
166 printf("Voiced level = %.2fdB, crest factor = %.2fdB\n", rms_to_dbm0(ms), rms_to_db(pk/ms));
167
168 #if defined(HAVE_FFTW3_H)
169 p = fftw_plan_dft_1d(8192, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
170 #else
171 p = fftw_create_plan(8192, FFTW_BACKWARD, FFTW_ESTIMATE);
172 #endif
173 for (i = 0; i < 8192; i++)
174 {
175 #if defined(HAVE_FFTW3_H)
176 in[i][0] = 0.0;
177 in[i][1] = 0.0;
178 #else
179 in[i].re = 0.0;
180 in[i].im = 0.0;
181 #endif
182 }
183 for (i = 1; i <= 3715; i++)
184 {
185 f = FAST_SAMPLE_RATE*i/8192.0;
186
187 #if 1
188 if (f < 50.0)
189 scale = -60.0;
190 else if (f < 100.0)
191 scale = scaling(f, 50.0, 100.0, -25.8, -12.8);
192 else if (f < 200.0)
193 scale = scaling(f, 100.0, 200.0, -12.8, 17.4);
194 else if (f < 215.0)
195 scale = scaling(f, 200.0, 215.0, 17.4, 17.8);
196 else if (f < 500.0)
197 scale = scaling(f, 215.0, 500.0, 17.8, 12.2);
198 else if (f < 1000.0)
199 scale = scaling(f, 500.0, 1000.0, 12.2, 7.2);
200 else if (f < 2850.0)
201 scale = scaling(f, 1000.0, 2850.0, 7.2, 0.0);
202 else if (f < 3600.0)
203 scale = scaling(f, 2850.0, 3600.0, 0.0, -2.0);
204 else if (f < 3660.0)
205 scale = scaling(f, 3600.0, 3660.0, -2.0, -20.0);
206 else if (f < 3680.0)
207 scale = scaling(f, 3600.0, 3680.0, -20.0, -30.0);
208 else
209 scale = -60.0;
210 #else
211 scale = 0.0;
212 #endif
213 #if defined(HAVE_FFTW3_H)
214 in[i][0] = ((rand() >> 10) & 0x1) ? 1.0 : -1.0;
215 in[i][0] *= pow(10.0, scale/20.0)*35.0; //305360
216 in[8192 - i][0] = -in[i][0];
217 #else
218 in[i].re = ((rand() >> 10) & 0x1) ? 1.0 : -1.0;
219 in[i].re *= pow(10.0, scale/20.0)*35.0; //305360
220 in[8192 - i].re = -in[i].re;
221 #endif
222 }
223 #if defined(HAVE_FFTW3_H)
224 fftw_execute(p);
225 #else
226 fftw_one(p, in, out);
227 #endif
228 for (i = 0; i < 8192; i++)
229 {
230 #if defined(HAVE_FFTW3_H)
231 noise_sound[i] = out[i][1];
232 #else
233 noise_sound[i] = out[i].im;
234 #endif
235 }
236 pk = peak(noise_sound, 8192);
237 ms = rms(noise_sound, 8192);
238 printf("Noise level = %.2fdB, crest factor = %.2fdB\n", rms_to_dbm0(ms), rms_to_db(pk/ms));
239
240 for (i = 0; i < 8192; i++)
241 silence_sound[i] = 0.0;
242
243 for (i = 0; i < 16; i++)
244 outframes = sf_writef_short(filehandle, voiced_sound, voiced_length);
245 printf("%d samples of voice\n", 16*voiced_length);
246 outframes = sf_writef_short(filehandle, noise_sound, 8192);
247 outframes = sf_writef_short(filehandle, noise_sound, C1_NOISE_SAMPLES - 8192);
248 printf("%d samples of noise\n", C1_NOISE_SAMPLES);
249 outframes = sf_writef_short(filehandle, silence_sound, C1_SILENCE_SAMPLES);
250 printf("%d samples of silence\n", C1_SILENCE_SAMPLES);
251
252 /* Now phase invert the C1 set of voice samples. */
253 voiced_length = sizeof(css_c1)/sizeof(css_c1[0]);
254 for (i = 0; i < voiced_length; i++)
255 voiced_sound[i] = -css_c1[i];
256 pk = peak(voiced_sound, voiced_length);
257 ms = rms(voiced_sound, voiced_length);
258 printf("Voiced level = %.2fdB, crest factor = %.2fdB\n", rms_to_dbm0(ms), rms_to_db(pk/ms));
259
260 for (i = 0; i < 8192; i++)
261 noise_sound[i] = -noise_sound[i];
262
263 for (i = 0; i < 16; i++)
264 outframes = sf_writef_short(filehandle, voiced_sound, voiced_length);
265 printf("%d samples of voice\n", 16*voiced_length);
266 outframes = sf_writef_short(filehandle, noise_sound, 8192);
267 outframes = sf_writef_short(filehandle, noise_sound, C1_NOISE_SAMPLES - 8192);
268 printf("%d samples of noise\n", C1_NOISE_SAMPLES);
269 outframes = sf_writef_short(filehandle, silence_sound, C1_SILENCE_SAMPLES);
270 printf("%d samples of silence\n", C1_SILENCE_SAMPLES);
271
272 if (sf_close(filehandle) != 0)
273 {
274 fprintf(stderr, " Cannot close speech file '%s'\n", "sound_c1.wav");
275 exit(2);
276 }
277
278 memset(&info, 0, sizeof(info));
279 info.frames = 0;
280 info.samplerate = FAST_SAMPLE_RATE;
281 info.channels = 1;
282 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
283 info.sections = 1;
284 info.seekable = 1;
285 if ((filehandle = sf_open("sound_c3.wav", SFM_WRITE, &info)) == NULL)
286 {
287 fprintf(stderr, " Failed to open result file\n");
288 exit(2);
289 }
290
291 printf("Generate C3\n");
292 /* Take the supplied set of C3 voice samples. */
293 voiced_length = (sizeof(css_c3)/sizeof(css_c3[0]));
294 for (i = 0; i < voiced_length; i++)
295 voiced_sound[i] = css_c3[i];
296 pk = peak(voiced_sound, voiced_length);
297 ms = rms(voiced_sound, voiced_length);
298 printf("Voiced level = %.2fdB, crest factor = %.2fdB\n", rms_to_dbm0(ms), rms_to_db(pk/ms));
299
300 awgn_init_dbm0(&noise_source, 7162534, rms_to_dbm0(ms));
301 for (i = 0; i < 8192; i++)
302 noise_sound[i] = awgn(&noise_source);
303 pk = peak(noise_sound, 8192);
304 ms = rms(noise_sound, 8192);
305 printf("Noise level = %.2fdB, crest factor = %.2fdB\n", rms_to_dbm0(ms), rms_to_db(pk/ms));
306
307 for (i = 0; i < 14; i++)
308 outframes = sf_writef_short(filehandle, voiced_sound, voiced_length);
309 printf("%d samples of voice\n", 14*voiced_length);
310
311 outframes = sf_writef_short(filehandle, noise_sound, 8192);
312 outframes = sf_writef_short(filehandle, noise_sound, C3_NOISE_SAMPLES - 8192);
313 printf("%d samples of noise\n", C3_NOISE_SAMPLES);
314 outframes = sf_writef_short(filehandle, silence_sound, C3_SILENCE_SAMPLES);
315 printf("%d samples of silence\n", C3_SILENCE_SAMPLES);
316
317 /* Now phase invert the set of voice samples. */
318 voiced_length = (sizeof(css_c3)/sizeof(css_c3[0]));
319 for (i = 0; i < voiced_length; i++)
320 voiced_sound[i] = -css_c3[i];
321 pk = peak(voiced_sound, voiced_length);
322 ms = rms(voiced_sound, voiced_length);
323 printf("Voiced level = %.2fdB, crest factor = %.2fdB\n", rms_to_dbm0(ms), rms_to_db(pk/ms));
324
325 /* Now phase invert the set of noise samples. */
326 for (i = 0; i < 8192; i++)
327 noise_sound[i] = -noise_sound[i];
328
329 for (i = 0; i < 14; i++)
330 outframes = sf_writef_short(filehandle, voiced_sound, voiced_length);
331 printf("%d samples of voice\n", 14*i);
332 outframes = sf_writef_short(filehandle, noise_sound, 8192);
333 outframes = sf_writef_short(filehandle, noise_sound, C3_NOISE_SAMPLES - 8192);
334 printf("%d samples of noise\n", C3_NOISE_SAMPLES);
335 outframes = sf_writef_short(filehandle, silence_sound, C3_SILENCE_SAMPLES);
336 printf("%d samples of silence\n", C3_SILENCE_SAMPLES);
337
338 if (sf_close(filehandle) != 0)
339 {
340 fprintf(stderr, " Cannot close speech file '%s'\n", "sound_c3.wav");
341 exit(2);
342 }
343
344 fftw_destroy_plan(p);
345 return 0;
346 }
347 /*- End of function --------------------------------------------------------*/
348 /*- End of file ------------------------------------------------------------*/

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