2
0

dds_tests.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. /*! \file */
  26. /*! \page dds_tests_page Direct digital synthesis tests
  27. \section dds_tests_page_sec_1 What does it do?
  28. ???.
  29. \section dds_tests_page_sec_2 How does it work?
  30. ???.
  31. */
  32. #if defined(HAVE_CONFIG_H)
  33. #include "config.h"
  34. #endif
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <fcntl.h>
  38. #include <memory.h>
  39. #include <sndfile.h>
  40. #include "spandsp.h"
  41. #include "spandsp-sim.h"
  42. #define OUTPUT_FILE_NAME "dds.wav"
  43. #define OUTPUT_FILE_NAME_COMPLEX "complex_dds.wav"
  44. #define SAMPLES_PER_CHUNK 8000
  45. int main(int argc, char *argv[])
  46. {
  47. int i;
  48. uint32_t phase;
  49. int32_t phase_inc;
  50. int outframes;
  51. complexf_t camp;
  52. int16_t buf[2*SAMPLES_PER_CHUNK];
  53. SNDFILE *outhandle;
  54. power_meter_t meter;
  55. power_meter_t meter_i;
  56. power_meter_t meter_q;
  57. int scale;
  58. power_meter_init(&meter, 10);
  59. printf("Non-complex DDS tests.\n");
  60. if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
  61. {
  62. fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME);
  63. exit(2);
  64. }
  65. phase = 0;
  66. printf("Test with 123.456789Hz.\n");
  67. phase_inc = dds_phase_rate(123.456789f);
  68. scale = dds_scaling_dbm0(-10.0f);
  69. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  70. {
  71. buf[i] = alaw_to_linear(linear_to_alaw((dds(&phase, phase_inc)*scale) >> 15));
  72. power_meter_update(&meter, buf[i]);
  73. }
  74. outframes = sf_writef_short(outhandle, buf, SAMPLES_PER_CHUNK);
  75. if (outframes != SAMPLES_PER_CHUNK)
  76. {
  77. fprintf(stderr, " Error writing audio file\n");
  78. exit(2);
  79. }
  80. printf("Level is %fdBOv/%fdBm0\n", power_meter_current_dbov(&meter), power_meter_current_dbm0(&meter));
  81. if (fabs(power_meter_current_dbm0(&meter) + 10.0f) > 0.1f)
  82. {
  83. printf("Test failed.\n");
  84. exit(2);
  85. }
  86. printf("Test with 12.3456789Hz.\n");
  87. phase_inc = dds_phase_rate(12.3456789f);
  88. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  89. {
  90. buf[i] = alaw_to_linear(linear_to_alaw(dds(&phase, phase_inc)));
  91. power_meter_update(&meter, buf[i]);
  92. }
  93. outframes = sf_writef_short(outhandle, buf, SAMPLES_PER_CHUNK);
  94. if (outframes != SAMPLES_PER_CHUNK)
  95. {
  96. fprintf(stderr, " Error writing audio file\n");
  97. exit(2);
  98. }
  99. printf("Level is %fdBOv/%fdBm0\n", power_meter_current_dbov(&meter), power_meter_current_dbm0(&meter));
  100. /* Use a wider tolerance for this very low frequency - the power meter will ripple */
  101. if (fabs(power_meter_current_dbov(&meter) + 3.02f) > 0.2f)
  102. {
  103. printf("Test failed.\n");
  104. exit(2);
  105. }
  106. printf("Test with 2345.6789Hz.\n");
  107. phase_inc = dds_phase_rate(2345.6789f);
  108. scale = dds_scaling_dbov(-10.0f);
  109. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  110. {
  111. buf[i] = alaw_to_linear(linear_to_alaw((dds(&phase, phase_inc)*scale) >> 15));
  112. power_meter_update(&meter, buf[i]);
  113. }
  114. outframes = sf_writef_short(outhandle, buf, SAMPLES_PER_CHUNK);
  115. if (outframes != SAMPLES_PER_CHUNK)
  116. {
  117. fprintf(stderr, " Error writing audio file\n");
  118. exit(2);
  119. }
  120. printf("Level is %fdBOv/%fdBm0\n", power_meter_current_dbov(&meter), power_meter_current_dbm0(&meter));
  121. if (fabs(power_meter_current_dbov(&meter) + 10.0f) > 0.1f)
  122. {
  123. printf("Test failed.\n");
  124. exit(2);
  125. }
  126. printf("Test with 3456.789Hz.\n");
  127. phase_inc = dds_phase_rate(3456.789f);
  128. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  129. {
  130. buf[i] = alaw_to_linear(linear_to_alaw(dds(&phase, phase_inc)));
  131. power_meter_update(&meter, buf[i]);
  132. }
  133. outframes = sf_writef_short(outhandle, buf, SAMPLES_PER_CHUNK);
  134. if (outframes != SAMPLES_PER_CHUNK)
  135. {
  136. fprintf(stderr, " Error writing audio file\n");
  137. exit(2);
  138. }
  139. printf("Level is %fdBOv/%fdBm0\n", power_meter_current_dbov(&meter), power_meter_current_dbm0(&meter));
  140. if (fabs(power_meter_current_dbov(&meter) + 3.02f) > 0.05f)
  141. {
  142. printf("Test failed.\n");
  143. exit(2);
  144. }
  145. if (sf_close_telephony(outhandle))
  146. {
  147. fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
  148. exit(2);
  149. }
  150. printf("Complex DDS tests,\n");
  151. if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME_COMPLEX, 2)) == NULL)
  152. {
  153. fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_COMPLEX);
  154. exit(2);
  155. }
  156. power_meter_init(&meter_i, 7);
  157. power_meter_init(&meter_q, 7);
  158. phase = 0;
  159. phase_inc = dds_phase_ratef(123.456789f);
  160. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  161. {
  162. camp = dds_complexf(&phase, phase_inc);
  163. buf[2*i] = camp.re*10000.0f;
  164. buf[2*i + 1] = camp.im*10000.0f;
  165. power_meter_update(&meter_i, buf[2*i]);
  166. power_meter_update(&meter_q, buf[2*i]);
  167. }
  168. outframes = sf_writef_short(outhandle, buf, SAMPLES_PER_CHUNK);
  169. if (outframes != SAMPLES_PER_CHUNK)
  170. {
  171. fprintf(stderr, " Error writing audio file\n");
  172. exit(2);
  173. }
  174. printf("Level is %fdBOv/%fdBm0, %fdBOv/%fdBm0\n",
  175. power_meter_current_dbov(&meter_i),
  176. power_meter_current_dbm0(&meter_i),
  177. power_meter_current_dbov(&meter_q),
  178. power_meter_current_dbm0(&meter_q));
  179. if (fabs(power_meter_current_dbov(&meter_i) + 13.42f) > 0.05f
  180. ||
  181. fabs(power_meter_current_dbov(&meter_q) + 13.42f) > 0.05f)
  182. {
  183. printf("Test failed.\n");
  184. exit(2);
  185. }
  186. if (sf_close_telephony(outhandle))
  187. {
  188. fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_COMPLEX);
  189. exit(2);
  190. }
  191. printf("Tests passed.\n");
  192. return 0;
  193. }
  194. /*- End of function --------------------------------------------------------*/
  195. /*- End of file ------------------------------------------------------------*/