switch_vad.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. switch_vad_state_t cur_state = SWITCH_VAD_STATE_NONE;
  72. switch_vad_t *vad = switch_vad_init(8000, 1);
  73. fst_requires(vad);
  74. int res = switch_vad_set_mode(vad, 0); // tone is detected as speech in mode 0
  75. fst_requires(res == 0);
  76. switch_vad_set_param(vad, "silence_ms", 400);
  77. switch_vad_set_param(vad, "voice_ms", 80);
  78. switch_vad_set_param(vad, "debug", 10);
  79. // generate a tone and pump it into the vad
  80. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 200 ms tone\n");
  81. duration = 200 / 20; // 200 ms
  82. while (--duration >= 0) {
  83. switch_vad_state_t new_state;
  84. pos = next_tone_frame(buf, 160, pos);
  85. new_state = switch_vad_process(vad, buf, 160);
  86. if (new_state != cur_state) got_transition++;
  87. cur_state = new_state;
  88. }
  89. fst_requires(got_transition == 2);
  90. fst_requires(cur_state == SWITCH_VAD_STATE_TALKING);
  91. // feed silence frames into the vad
  92. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 1000 ms silence\n");
  93. duration = 1000 / 20; // 1000 ms
  94. got_transition = 0;
  95. next_silence_frame(buf, 160);
  96. while (--duration >= 0) {
  97. switch_vad_state_t new_state = switch_vad_process(vad, buf, 160);
  98. if (new_state != cur_state) got_transition++;
  99. cur_state = new_state;
  100. }
  101. fst_requires(got_transition == 2);
  102. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  103. // generate a tone < voice_ms
  104. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 40 ms tone\n");
  105. duration = 40 / 20; // 40 ms
  106. got_transition = 0;
  107. while (--duration >= 0) {
  108. switch_vad_state_t new_state;
  109. pos = next_tone_frame(buf, 160, pos);
  110. new_state = switch_vad_process(vad, buf, 160);
  111. if (new_state != cur_state) got_transition++;
  112. cur_state = new_state;
  113. }
  114. fst_requires(got_transition == 0);
  115. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  116. // continue tone > voice_ms
  117. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Continue with 60 ms tone\n");
  118. duration = 60 / 20; // 60 ms
  119. got_transition = 0;
  120. while (--duration >= 0) {
  121. switch_vad_state_t new_state;
  122. pos = next_tone_frame(buf, 160, pos);
  123. new_state = switch_vad_process(vad, buf, 160);
  124. if (new_state != cur_state) got_transition++;
  125. cur_state = new_state;
  126. }
  127. fst_requires(got_transition == 1);
  128. fst_requires(cur_state == SWITCH_VAD_STATE_START_TALKING);
  129. free(buf);
  130. switch_vad_destroy(&vad);
  131. fst_check(vad == NULL);
  132. }
  133. FST_TEST_END()
  134. #endif
  135. FST_TEST_BEGIN(energy)
  136. {
  137. int16_t *buf = malloc(sizeof(int16_t) * 160);
  138. int duration;
  139. float pos = 0.0;
  140. int got_transition = 0;
  141. switch_vad_state_t cur_state = SWITCH_VAD_STATE_NONE;
  142. switch_vad_t *vad = switch_vad_init(8000, 1);
  143. fst_requires(vad);
  144. int res = switch_vad_set_mode(vad, -1);
  145. fst_requires(res == 0);
  146. switch_vad_set_param(vad, "silence_ms", 400);
  147. switch_vad_set_param(vad, "voice_ms", 80);
  148. switch_vad_set_param(vad, "debug", 10);
  149. // generate a tone and pump it into the vad
  150. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 200 ms tone\n");
  151. duration = 200 / 20; // 200 ms
  152. while (--duration >= 0) {
  153. switch_vad_state_t new_state;
  154. pos = next_tone_frame(buf, 160, pos);
  155. new_state = switch_vad_process(vad, buf, 160);
  156. if (new_state != cur_state) got_transition++;
  157. cur_state = new_state;
  158. }
  159. fst_requires(got_transition == 2);
  160. fst_requires(cur_state == SWITCH_VAD_STATE_TALKING);
  161. // feed silence frames into the vad
  162. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 1000 ms silence\n");
  163. duration = 1000 / 20; // 1000 ms
  164. got_transition = 0;
  165. next_silence_frame(buf, 160);
  166. while (--duration >= 0) {
  167. switch_vad_state_t new_state = switch_vad_process(vad, buf, 160);
  168. if (new_state != cur_state) got_transition++;
  169. cur_state = new_state;
  170. }
  171. fst_requires(got_transition == 2);
  172. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  173. // generate a tone < voice_ms
  174. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Start 40 ms tone\n");
  175. duration = 40 / 20; // 40 ms
  176. got_transition = 0;
  177. while (--duration >= 0) {
  178. switch_vad_state_t new_state;
  179. pos = next_tone_frame(buf, 160, pos);
  180. new_state = switch_vad_process(vad, buf, 160);
  181. if (new_state != cur_state) got_transition++;
  182. cur_state = new_state;
  183. }
  184. fst_requires(got_transition == 0);
  185. fst_requires(cur_state == SWITCH_VAD_STATE_NONE);
  186. // continue tone > voice_ms
  187. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Continue with 60 ms tone\n");
  188. duration = 60 / 20; // 60 ms
  189. got_transition = 0;
  190. while (--duration >= 0) {
  191. switch_vad_state_t new_state;
  192. pos = next_tone_frame(buf, 160, pos);
  193. new_state = switch_vad_process(vad, buf, 160);
  194. if (new_state != cur_state) got_transition++;
  195. cur_state = new_state;
  196. }
  197. fst_requires(got_transition == 1);
  198. fst_requires(cur_state == SWITCH_VAD_STATE_START_TALKING);
  199. free(buf);
  200. switch_vad_destroy(&vad);
  201. fst_check(vad == NULL);
  202. }
  203. FST_TEST_END()
  204. }
  205. FST_SUITE_END()
  206. }
  207. FST_CORE_END()