5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * dds_tests.c
|
|
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: dds_tests.c,v 1.17 2006/11/19 14:07:26 steveu Exp $
|
|
26 */
|
|
27
|
|
28 /*! \file */
|
|
29
|
|
30 /*! \page dds_tests_page Direct digital synthesis tests
|
|
31 \section dds_tests_page_sec_1 What does it do?
|
|
32 ???.
|
|
33
|
|
34 \section dds_tests_page_sec_2 How does it work?
|
|
35 ???.
|
|
36 */
|
|
37
|
|
38 #ifdef HAVE_CONFIG_H
|
|
39 #include "config.h"
|
|
40 #endif
|
|
41
|
|
42 #include <inttypes.h>
|
|
43 #include <stdlib.h>
|
|
44 #include <stdio.h>
|
|
45 #include <fcntl.h>
|
|
46 #include <memory.h>
|
|
47 #if defined(HAVE_TGMATH_H)
|
|
48 #include <tgmath.h>
|
|
49 #endif
|
|
50 #if defined(HAVE_MATH_H)
|
|
51 #include <math.h>
|
|
52 #endif
|
|
53 #include <audiofile.h>
|
|
54 #include <tiffio.h>
|
|
55
|
|
56 #include "spandsp.h"
|
|
57
|
|
58 #define OUTPUT_FILE_NAME "dds.wav"
|
|
59 #define OUTPUT_FILE_NAME_COMPLEX "complex_dds.wav"
|
|
60
|
|
61 #define SAMPLES_PER_CHUNK 8000
|
|
62
|
|
63 int main(int argc, char *argv[])
|
|
64 {
|
|
65 int i;
|
|
66 uint32_t phase;
|
|
67 int32_t phase_inc;
|
|
68 int outframes;
|
|
69 complexf_t camp;
|
|
70 int16_t buf[2*SAMPLES_PER_CHUNK];
|
|
71 AFfilehandle outhandle;
|
|
72 AFfilesetup filesetup;
|
|
73 power_meter_t meter;
|
|
74 power_meter_t meter_i;
|
|
75 power_meter_t meter_q;
|
|
76
|
|
77 power_meter_init(&meter, 10);
|
|
78
|
|
79 printf("Non-complex DDS tests.\n");
|
|
80 if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
|
|
81 {
|
|
82 fprintf(stderr, " Failed to create file setup\n");
|
|
83 exit(2);
|
|
84 }
|
|
85 afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
|
|
86 afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
|
|
87 afInitFileFormat(filesetup, AF_FILE_WAVE);
|
|
88 afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);
|
|
89
|
|
90 if ((outhandle = afOpenFile(OUTPUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
|
|
91 {
|
|
92 fprintf(stderr, " Cannot create wave file '%s'\n", OUTPUT_FILE_NAME);
|
|
93 exit(2);
|
|
94 }
|
|
95
|
|
96 phase = 0;
|
|
97
|
|
98 printf("Test with 123.456789Hz.\n");
|
|
99 phase_inc = dds_phase_rate(123.456789);
|
|
100 for (i = 0; i < SAMPLES_PER_CHUNK; i++)
|
|
101 {
|
|
102 buf[i] = alaw_to_linear(linear_to_alaw(dds(&phase, phase_inc)));
|
|
103 power_meter_update(&meter, buf[i]);
|
|
104 }
|
|
105 outframes = afWriteFrames(outhandle,
|
|
106 AF_DEFAULT_TRACK,
|
|
107 buf,
|
|
108 SAMPLES_PER_CHUNK);
|
|
109 if (outframes != SAMPLES_PER_CHUNK)
|
|
110 {
|
|
111 fprintf(stderr, " Error writing wave file\n");
|
|
112 exit(2);
|
|
113 }
|
|
114 printf("Level is %fdBOv\n", power_meter_dbov(&meter));
|
|
115 if (fabs(power_meter_dbov(&meter) + 3.02) > 0.05)
|
|
116 {
|
|
117 printf("Test failed.\n");
|
|
118 exit(2);
|
|
119 }
|
|
120
|
|
121 printf("Test with 12.3456789Hz.\n");
|
|
122 phase_inc = dds_phase_rate(12.3456789);
|
|
123 for (i = 0; i < SAMPLES_PER_CHUNK; i++)
|
|
124 {
|
|
125 buf[i] = alaw_to_linear(linear_to_alaw(dds(&phase, phase_inc)));
|
|
126 power_meter_update(&meter, buf[i]);
|
|
127 }
|
|
128 outframes = afWriteFrames(outhandle,
|
|
129 AF_DEFAULT_TRACK,
|
|
130 buf,
|
|
131 SAMPLES_PER_CHUNK);
|
|
132 if (outframes != SAMPLES_PER_CHUNK)
|
|
133 {
|
|
134 fprintf(stderr, " Error writing wave file\n");
|
|
135 exit(2);
|
|
136 }
|
|
137 printf("Level is %fdBOv\n", power_meter_dbov(&meter));
|
|
138 /* Use a wider tolerance for this very low frequency - the power meter will ripple */
|
|
139 if (fabs(power_meter_dbov(&meter) + 3.02) > 0.2)
|
|
140 {
|
|
141 printf("Test failed.\n");
|
|
142 exit(2);
|
|
143 }
|
|
144
|
|
145 printf("Test with 2345.6789Hz.\n");
|
|
146 phase_inc = dds_phase_rate(2345.6789);
|
|
147 for (i = 0; i < SAMPLES_PER_CHUNK; i++)
|
|
148 {
|
|
149 buf[i] = alaw_to_linear(linear_to_alaw(dds(&phase, phase_inc)));
|
|
150 power_meter_update(&meter, buf[i]);
|
|
151 }
|
|
152 outframes = afWriteFrames(outhandle,
|
|
153 AF_DEFAULT_TRACK,
|
|
154 buf,
|
|
155 SAMPLES_PER_CHUNK);
|
|
156 if (outframes != SAMPLES_PER_CHUNK)
|
|
157 {
|
|
158 fprintf(stderr, " Error writing wave file\n");
|
|
159 exit(2);
|
|
160 }
|
|
161 printf("Level is %fdBOv\n", power_meter_dbov(&meter));
|
|
162 if (fabs(power_meter_dbov(&meter) + 3.02) > 0.05)
|
|
163 {
|
|
164 printf("Test failed.\n");
|
|
165 exit(2);
|
|
166 }
|
|
167
|
|
168 printf("Test with 3456.789Hz.\n");
|
|
169 phase_inc = dds_phase_rate(3456.789);
|
|
170 for (i = 0; i < SAMPLES_PER_CHUNK; i++)
|
|
171 {
|
|
172 buf[i] = alaw_to_linear(linear_to_alaw(dds(&phase, phase_inc)));
|
|
173 power_meter_update(&meter, buf[i]);
|
|
174 }
|
|
175 outframes = afWriteFrames(outhandle,
|
|
176 AF_DEFAULT_TRACK,
|
|
177 buf,
|
|
178 SAMPLES_PER_CHUNK);
|
|
179 if (outframes != SAMPLES_PER_CHUNK)
|
|
180 {
|
|
181 fprintf(stderr, " Error writing wave file\n");
|
|
182 exit(2);
|
|
183 }
|
|
184 printf("Level is %fdBOv\n", power_meter_dbov(&meter));
|
|
185 if (fabs(power_meter_dbov(&meter) + 3.02) > 0.05)
|
|
186 {
|
|
187 printf("Test failed.\n");
|
|
188 exit(2);
|
|
189 }
|
|
190
|
|
191 if (afCloseFile(outhandle) != 0)
|
|
192 {
|
|
193 fprintf(stderr, " Cannot close wave file '%s'\n", OUTPUT_FILE_NAME);
|
|
194 exit(2);
|
|
195 }
|
|
196 afFreeFileSetup(filesetup);
|
|
197
|
|
198 printf("Complex DDS tests,\n");
|
|
199 if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
|
|
200 {
|
|
201 fprintf(stderr, " Failed to create file setup\n");
|
|
202 exit(2);
|
|
203 }
|
|
204 afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
|
|
205 afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
|
|
206 afInitFileFormat(filesetup, AF_FILE_WAVE);
|
|
207 afInitChannels(filesetup, AF_DEFAULT_TRACK, 2);
|
|
208
|
|
209 if ((outhandle = afOpenFile(OUTPUT_FILE_NAME_COMPLEX, "w", filesetup)) == AF_NULL_FILEHANDLE)
|
|
210 {
|
|
211 fprintf(stderr, " Cannot create wave file '%s'\n", OUTPUT_FILE_NAME_COMPLEX);
|
|
212 exit(2);
|
|
213 }
|
|
214
|
|
215 power_meter_init(&meter_i, 7);
|
|
216 power_meter_init(&meter_q, 7);
|
|
217
|
|
218 phase = 0;
|
|
219 phase_inc = dds_phase_ratef(123.456789);
|
|
220 for (i = 0; i < SAMPLES_PER_CHUNK; i++)
|
|
221 {
|
|
222 camp = dds_complexf(&phase, phase_inc);
|
|
223 buf[2*i] = camp.re*10000.0;
|
|
224 buf[2*i + 1] = camp.im*10000.0;
|
|
225 power_meter_update(&meter_i, buf[2*i]);
|
|
226 power_meter_update(&meter_q, buf[2*i]);
|
|
227 }
|
|
228 outframes = afWriteFrames(outhandle,
|
|
229 AF_DEFAULT_TRACK,
|
|
230 buf,
|
|
231 SAMPLES_PER_CHUNK);
|
|
232 if (outframes != SAMPLES_PER_CHUNK)
|
|
233 {
|
|
234 fprintf(stderr, " Error writing wave file\n");
|
|
235 exit(2);
|
|
236 }
|
|
237 printf("Level is %fdBOv/%fdBOv\n", power_meter_dbov(&meter_i), power_meter_dbov(&meter_q));
|
|
238 if (fabs(power_meter_dbov(&meter_i) + 13.42) > 0.05
|
|
239 ||
|
|
240 fabs(power_meter_dbov(&meter_q) + 13.42) > 0.05)
|
|
241 {
|
|
242 printf("Test failed.\n");
|
|
243 exit(2);
|
|
244 }
|
|
245
|
|
246 if (afCloseFile(outhandle) != 0)
|
|
247 {
|
|
248 fprintf(stderr, " Cannot close wave file '%s'\n", OUTPUT_FILE_NAME_COMPLEX);
|
|
249 exit(2);
|
|
250 }
|
|
251 afFreeFileSetup(filesetup);
|
|
252
|
|
253 printf("Tests passed.\n");
|
|
254 return 0;
|
|
255 }
|
|
256 /*- End of function --------------------------------------------------------*/
|
|
257 /*- End of file ------------------------------------------------------------*/
|