switch_vad.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  3. * Copyright (C) 2020, Anthony Minessale II <anthm@freeswitch.org>
  4. *
  5. * Version: MPL 1.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License Version
  8. * 1.1 (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. * for the specific language governing rights and limitations under the
  15. * License.
  16. *
  17. * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  18. *
  19. * The Initial Developer of the Original Code is
  20. * Anthony Minessale II <anthm@freeswitch.org>
  21. * Portions created by the Initial Developer are Copyright (C)
  22. * the Initial Developer. All Rights Reserved.
  23. *
  24. * Contributor(s):
  25. * Chris Rienzo <chris@signalwire.com>
  26. *
  27. *
  28. * switch_vad.c -- VAD tests
  29. *
  30. */
  31. #include <switch.h>
  32. #include <stdlib.h>
  33. #include <test/switch_test.h>
  34. static float next_tone_frame(int16_t *buf, unsigned int samples, float pos)
  35. {
  36. // make sine wave of amplitude 7000 for 8000Hz sample rate VAD
  37. float step = 600.0 / 8000.0 * 2.0 * M_PI;
  38. unsigned int i;
  39. for (i = 0; i < samples; i++) {
  40. buf[i] = (int16_t)(7000.0 * sinf(pos));
  41. pos += step;
  42. }
  43. return pos;
  44. }
  45. static void next_silence_frame(int16_t *buf, unsigned int samples)
  46. {
  47. unsigned int i;
  48. for (i = 0; i < samples; i++) {
  49. buf[i] = 0;
  50. }
  51. }
  52. FST_CORE_BEGIN("./conf")
  53. {
  54. FST_SUITE_BEGIN(switch_vad)
  55. {
  56. FST_SETUP_BEGIN()
  57. {
  58. }
  59. FST_SETUP_END()
  60. FST_TEARDOWN_BEGIN()
  61. {
  62. }
  63. FST_TEARDOWN_END()
  64. #ifdef SWITCH_HAVE_FVAD
  65. FST_TEST_BEGIN(fvad_mode_0)
  66. {
  67. int16_t *buf = malloc(sizeof(int16_t) * 160);
  68. int duration;
  69. float pos = 0.0;
  70. int got_transition = 0;
  71. int res;
  72. switch_vad_state_t cur_state = SWITCH_VAD_STATE_NONE;
  73. switch_vad_t *vad = switch_vad_init(8000, 1);
  74. fst_requires(vad);
  75. res = switch_vad_set_mode(vad, 0); // tone is detected as speech in mode 0
  76. fst_requires(res == 0);
  77. switch_vad_set_param(vad, "silence_ms", 400);
  78. switch_vad_set_param(vad, "voice_ms", 80);
  79. switch_vad_set_param(vad, "debug", 10);
  80. // generate a tone and pump it into the vad
  81. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 200 ms tone\n");
  82. duration = 200 / 20; // 200 ms
  83. while (--duration >= 0) {
  84. switch_vad_state_t new_state;
  85. pos = next_tone_frame(buf, 160, pos);
  86. new_state = switch_vad_process(vad, buf, 160);
  87. if (new_state != cur_state) got_transition++;
  88. cur_state = new_state;
  89. }
  90. fst_requires(got_transition == 2);
  91. fst_requires(cur_state == SWITCH_VAD_STATE_TALKING);
  92. // feed silence frames into the vad
  93. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 1000 ms silence\n");
  94. duration = 1000 / 20; // 1000 ms
  95. got_transition = 0;
  96. next_silence_frame(buf, 160);
  97. while (--duration >= 0) {
  98. switch_vad_state_t new_state = switch_vad_process(vad, buf, 160);
  99. if (new_state != cur_state) got_transition++;
  100. cur_state = new_state;
  101. }
  102. fst_requires(got_transition == 2);
  103. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  104. // generate a tone < voice_ms
  105. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 40 ms tone\n");
  106. duration = 40 / 20; // 40 ms
  107. got_transition = 0;
  108. while (--duration >= 0) {
  109. switch_vad_state_t new_state;
  110. pos = next_tone_frame(buf, 160, pos);
  111. new_state = switch_vad_process(vad, buf, 160);
  112. if (new_state != cur_state) got_transition++;
  113. cur_state = new_state;
  114. }
  115. fst_requires(got_transition == 0);
  116. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  117. // continue tone > voice_ms
  118. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Continue with 60 ms tone\n");
  119. duration = 60 / 20; // 60 ms
  120. got_transition = 0;
  121. while (--duration >= 0) {
  122. switch_vad_state_t new_state;
  123. pos = next_tone_frame(buf, 160, pos);
  124. new_state = switch_vad_process(vad, buf, 160);
  125. if (new_state != cur_state) got_transition++;
  126. cur_state = new_state;
  127. }
  128. fst_requires(got_transition == 1);
  129. fst_requires(cur_state == SWITCH_VAD_STATE_START_TALKING);
  130. free(buf);
  131. switch_vad_destroy(&vad);
  132. fst_check(vad == NULL);
  133. }
  134. FST_TEST_END()
  135. #endif
  136. FST_TEST_BEGIN(energy)
  137. {
  138. int res;
  139. int16_t *buf = malloc(sizeof(int16_t) * 160);
  140. int duration;
  141. float pos = 0.0;
  142. int got_transition = 0;
  143. switch_vad_state_t cur_state = SWITCH_VAD_STATE_NONE;
  144. switch_vad_t *vad = switch_vad_init(8000, 1);
  145. fst_requires(vad);
  146. res = switch_vad_set_mode(vad, -1);
  147. fst_requires(res == 0);
  148. switch_vad_set_param(vad, "silence_ms", 400);
  149. switch_vad_set_param(vad, "voice_ms", 80);
  150. switch_vad_set_param(vad, "debug", 10);
  151. // generate a tone and pump it into the vad
  152. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 200 ms tone\n");
  153. duration = 200 / 20; // 200 ms
  154. while (--duration >= 0) {
  155. switch_vad_state_t new_state;
  156. pos = next_tone_frame(buf, 160, pos);
  157. new_state = switch_vad_process(vad, buf, 160);
  158. if (new_state != cur_state) got_transition++;
  159. cur_state = new_state;
  160. }
  161. fst_requires(got_transition == 2);
  162. fst_requires(cur_state == SWITCH_VAD_STATE_TALKING);
  163. // feed silence frames into the vad
  164. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 1000 ms silence\n");
  165. duration = 1000 / 20; // 1000 ms
  166. got_transition = 0;
  167. next_silence_frame(buf, 160);
  168. while (--duration >= 0) {
  169. switch_vad_state_t new_state = switch_vad_process(vad, buf, 160);
  170. if (new_state != cur_state) got_transition++;
  171. cur_state = new_state;
  172. }
  173. fst_requires(got_transition == 2);
  174. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  175. // generate a tone < voice_ms
  176. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 40 ms tone\n");
  177. duration = 40 / 20; // 40 ms
  178. got_transition = 0;
  179. while (--duration >= 0) {
  180. switch_vad_state_t new_state;
  181. pos = next_tone_frame(buf, 160, pos);
  182. new_state = switch_vad_process(vad, buf, 160);
  183. if (new_state != cur_state) got_transition++;
  184. cur_state = new_state;
  185. }
  186. fst_requires(got_transition == 0);
  187. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  188. // continue tone > voice_ms
  189. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Continue with 60 ms tone\n");
  190. duration = 60 / 20; // 60 ms
  191. got_transition = 0;
  192. while (--duration >= 0) {
  193. switch_vad_state_t new_state;
  194. pos = next_tone_frame(buf, 160, pos);
  195. new_state = switch_vad_process(vad, buf, 160);
  196. if (new_state != cur_state) got_transition++;
  197. cur_state = new_state;
  198. }
  199. fst_requires(got_transition == 1);
  200. fst_requires(cur_state == SWITCH_VAD_STATE_START_TALKING);
  201. free(buf);
  202. switch_vad_destroy(&vad);
  203. fst_check(vad == NULL);
  204. }
  205. FST_TEST_END()
  206. }
  207. FST_SUITE_END()
  208. }
  209. FST_CORE_END()