audiotone.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include "precompile.h"
  2. #include "audiotone.h"
  3. #include "audioengine.h"
  4. #include <stddef.h>
  5. #include <math.h>
  6. #define AMP 12288
  7. #define MAX_DIGIT 16
  8. #ifndef M_PI
  9. # define M_PI ((float)3.141592653589793238462643383279)
  10. #endif
  11. #define DATA float
  12. #define GEN_INIT(var,R,F,A) var.a = (DATA) (2.0 * sin(M_PI * F / R)); \
  13. var.s0 = 0; \
  14. var.s1 = (DATA)(0 - (int)A)
  15. #define GEN_SAMP(val,var) var.s0 = var.s0 - var.a * var.s1; \
  16. var.s1 = var.s1 + var.a * var.s0; \
  17. val = (short) var.s0
  18. static void init_generate_single_tone(struct gen_state *state,
  19. unsigned clock_rate,
  20. unsigned freq,
  21. unsigned vol)
  22. {
  23. GEN_INIT(state->tone1,clock_rate,freq,vol);
  24. state->has_tone2 = FALSE;
  25. }
  26. static void generate_single_tone(struct gen_state *state,
  27. unsigned channel_count,
  28. unsigned samples,
  29. short buf[])
  30. {
  31. short *end = buf + samples;
  32. if (channel_count==1) {
  33. while (buf < end) {
  34. GEN_SAMP(*buf++, state->tone1);
  35. }
  36. } else if (channel_count == 2) {
  37. while (buf < end) {
  38. GEN_SAMP(*buf, state->tone1);
  39. *(buf+1) = *buf;
  40. buf += 2;
  41. }
  42. }
  43. }
  44. static void init_generate_dual_tone(struct gen_state *state,
  45. unsigned clock_rate,
  46. unsigned freq1,
  47. unsigned freq2,
  48. unsigned vol)
  49. {
  50. GEN_INIT(state->tone1,clock_rate,freq1,vol);
  51. GEN_INIT(state->tone2,clock_rate,freq2,vol);
  52. state->has_tone2 = TRUE;
  53. }
  54. static void generate_dual_tone(struct gen_state *state,
  55. unsigned channel_count,
  56. unsigned samples,
  57. short buf[])
  58. {
  59. short *end = buf + samples;
  60. if (channel_count==1) {
  61. int val, val2;
  62. while (buf < end) {
  63. GEN_SAMP(val, state->tone1);
  64. GEN_SAMP(val2, state->tone2);
  65. *buf++ = (short)((val+val2) >> 1);
  66. }
  67. } else if (channel_count == 2) {
  68. int val, val2;
  69. while (buf < end) {
  70. GEN_SAMP(val, state->tone1);
  71. GEN_SAMP(val2, state->tone2);
  72. val = (val + val2) >> 1;
  73. *buf++ = (short)val;
  74. *buf++ = (short)val;
  75. }
  76. }
  77. }
  78. static void init_generate_tone(struct gen_state *state,
  79. unsigned clock_rate,
  80. unsigned freq1,
  81. unsigned freq2,
  82. unsigned vol)
  83. {
  84. if (freq2)
  85. init_generate_dual_tone(state, clock_rate, freq1, freq2 ,vol);
  86. else
  87. init_generate_single_tone(state, clock_rate, freq1,vol);
  88. }
  89. static void generate_tone(struct gen_state *state,
  90. unsigned channel_count,
  91. unsigned samples,
  92. short buf[])
  93. {
  94. if (!state->has_tone2)
  95. generate_single_tone(state, channel_count, samples, buf);
  96. else
  97. generate_dual_tone(state, channel_count, samples, buf);
  98. }
  99. /****************************************************************************/
  100. enum flags
  101. {
  102. TONE_INITIALIZED = 1,
  103. TONE_ENABLE_FADE = 2
  104. };
  105. static struct {
  106. char digit; /**< The ASCI identification for the digit. */
  107. short freq1; /**< First frequency. */
  108. short freq2; /**< Optional second frequency. */
  109. }digit_map[MAX_DIGIT] = {
  110. { '0', 941, 1336 },
  111. { '1', 697, 1209 },
  112. { '2', 697, 1336 },
  113. { '3', 697, 1477 },
  114. { '4', 770, 1209 },
  115. { '5', 770, 1336 },
  116. { '6', 770, 1477 },
  117. { '7', 852, 1209 },
  118. { '8', 852, 1336 },
  119. { '9', 852, 1477 },
  120. { 'a', 697, 1633 },
  121. { 'b', 770, 1633 },
  122. { 'c', 852, 1633 },
  123. { 'd', 941, 1633 },
  124. { '*', 941, 1209 },
  125. { '#', 941, 1477 },
  126. };
  127. static void lock(audiotone_t *tone)
  128. {
  129. EnterCriticalSection(&tone->lock);
  130. }
  131. static void unlock(audiotone_t *tone)
  132. {
  133. LeaveCriticalSection(&tone->lock);
  134. }
  135. static apr_status_t read_frame(void *self, audioframe_t *frame)
  136. {
  137. audiotone_t *tone = CONTAINING_RECORD(self, audiotone_t, base);
  138. short *dst, *end;
  139. lock(tone);
  140. if (tone->dig_fi) {
  141. if ((tone->options|tone->playback_options)&TONEGEN_LOOP) {
  142. tone->dig_fi = 0;
  143. tone->dig_samples = 0;
  144. } else {
  145. unlock(tone);
  146. return APR_EGENERAL;
  147. }
  148. }
  149. dst = (short*)frame->buffer;
  150. end = dst + tone->ptime * 8000 / 1000;
  151. while (dst < end) {
  152. unsigned required, cnt, on_samp, off_samp;
  153. required = end - dst;
  154. on_samp = tone->on_msec * tone->clock / 1000;
  155. off_samp = tone->off_msec * tone->clock / 1000;
  156. if (tone->dig_samples == 0 && !(tone->flags & TONE_INITIALIZED)) {
  157. init_generate_tone(&tone->state, tone->clock, tone->freq1, tone->freq2, tone->volume);
  158. tone->flags |= TONE_INITIALIZED;
  159. }
  160. /* Add tone signal */
  161. if (tone->dig_samples < on_samp) {
  162. cnt = on_samp - tone->dig_samples;
  163. if (cnt > required)
  164. cnt = required;
  165. generate_tone(&tone->state, 1, cnt, dst);
  166. dst += cnt;
  167. tone->dig_samples += cnt;
  168. required -= cnt;
  169. if ((tone->flags & TONE_ENABLE_FADE) && tone->dig_samples == cnt) {
  170. /* Fade in */
  171. short *samp = (dst - cnt);
  172. short *end;
  173. if (cnt > tone->fade_in_len)
  174. cnt = tone->fade_in_len;
  175. end = samp + cnt;
  176. if (cnt) {
  177. const unsigned step = 0xFFFF / cnt;
  178. unsigned scale = 0;
  179. for (; samp < end; ++samp) {
  180. (*samp) = (short)(((*samp) * scale) >> 16);
  181. scale += step;
  182. }
  183. }
  184. } else if ((tone->flags & TONE_ENABLE_FADE) && tone->dig_samples==on_samp) {
  185. /* Fade out */
  186. if (cnt > tone->fade_out_len)
  187. cnt = tone->fade_out_len;
  188. if (cnt) {
  189. short *samp = (dst - cnt);
  190. const unsigned step = 0xFFFF / cnt;
  191. unsigned scale = 0xFFFF - step;
  192. for (; samp < dst; ++samp) {
  193. (*samp) = (short)(((*samp) * scale) >> 16);
  194. scale -= step;
  195. }
  196. }
  197. }
  198. if (dst == end)
  199. break;
  200. }
  201. /* Add silence signal */
  202. cnt = off_samp + on_samp - tone->dig_samples;
  203. if (cnt > required)
  204. cnt = required;
  205. memset(dst, 0, cnt << 1);
  206. dst += cnt;
  207. tone->dig_samples += cnt;
  208. }
  209. if (dst < end)
  210. memset(dst, 0, (end-dst)<<1);
  211. frame->size = 2 * tone->ptime * 8000 / 1000;
  212. if (tone->dig_samples >= tone->on_msec+tone->off_msec * tone->clock / 1000) {
  213. tone->dig_fi ++;
  214. }
  215. unlock(tone);
  216. return APR_SUCCESS;
  217. }
  218. static audiostream_vtbl_t g_stream_vtbl = {
  219. &read_frame,
  220. NULL,
  221. };
  222. apr_status_t audiotone_create(apr_pool_t *pool, audioengine_t *engine, int options, int clock, int ptime, audiotone_t **p_tone)
  223. {
  224. audiotone_t *tone;
  225. tone = apr_palloc(pool, sizeof(audiotone_t));
  226. memset(tone, 0, sizeof(audiotone_t));
  227. audiostream_init(engine, &g_stream_vtbl, &tone->base);
  228. tone->base.direction = STREAM_DIR_READ;
  229. tone->clock = clock;
  230. tone->ptime = ptime;
  231. tone->options = options;
  232. tone->fade_in_len = 1 * clock / 1000;
  233. tone->fade_out_len = 2 * clock / 1000;
  234. tone->dig_fi = TRUE;
  235. InitializeCriticalSection(&tone->lock);
  236. *p_tone = tone;
  237. return APR_SUCCESS;
  238. }
  239. void audiotone_destroy(audiotone_t *tone)
  240. {
  241. DeleteCriticalSection(&tone->lock);
  242. }
  243. apr_status_t audiotone_play_start_digit(audiotone_t *tone,
  244. int digit,
  245. int on_msec,
  246. int off_msec,
  247. int volume,
  248. int options)
  249. {
  250. int i;
  251. lock(tone);
  252. tone->playback_options = options;
  253. for (i = 0; i < MAX_DIGIT; ++i) {
  254. if (digit_map[i].digit == digit)
  255. break;
  256. }
  257. if (i == MAX_DIGIT) {
  258. unlock(tone);
  259. return APR_EINVAL;
  260. }
  261. tone->freq1 = digit_map[i].freq1;
  262. tone->freq2 = digit_map[i].freq2;
  263. tone->on_msec = on_msec;
  264. tone->off_msec = off_msec;
  265. tone->volume = volume;
  266. if (tone->volume == 0)
  267. tone->volume = AMP;
  268. else if (tone->volume < 0)
  269. tone->volume = -tone->volume;
  270. tone->dig_samples = 0;
  271. tone->dig_fi = 0;
  272. tone->flags = 0;
  273. if (tone->off_msec)
  274. tone->flags |= TONE_ENABLE_FADE;
  275. unlock(tone);
  276. return APR_SUCCESS;
  277. }
  278. apr_status_t audiotone_play_start_tone(audiotone_t *tone,
  279. int freq1,
  280. int freq2,
  281. int on_msec,
  282. int off_msec,
  283. int volume,
  284. int options)
  285. {
  286. lock(tone);
  287. tone->playback_options = options;
  288. tone->freq1 = freq1;
  289. tone->freq2 = freq2;
  290. tone->on_msec = on_msec;
  291. tone->off_msec = off_msec;
  292. tone->volume = volume;
  293. if (tone->volume == 0)
  294. tone->volume = AMP;
  295. else if (tone->volume < 0)
  296. tone->volume = -tone->volume;
  297. tone->dig_samples = 0;
  298. tone->dig_fi = 0;
  299. tone->flags = 0;
  300. if (tone->off_msec)
  301. tone->flags |= TONE_ENABLE_FADE;
  302. unlock(tone);
  303. return APR_SUCCESS;
  304. }
  305. apr_status_t audiotone_play_end(audiotone_t *tone)
  306. {
  307. lock(tone);
  308. tone->dig_fi = 1;
  309. tone->dig_samples = 0;
  310. tone->flags = 0;
  311. tone->playback_options = 0;
  312. unlock(tone);
  313. return APR_SUCCESS;
  314. }