audiodsp.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "precompile.h"
  2. #include "audiodsp.h"
  3. #include "audiocontext.h"
  4. #include "audiolog.h"
  5. #include <speex/speex_echo.h>
  6. #include <speex/speex_preprocess.h>
  7. static apr_status_t read_frame(void *self, audioframe_t *frame)
  8. {
  9. audiodsp_t *dsp = CONTAINING_RECORD(self, audiodsp_t, base);
  10. apr_status_t status;
  11. if (dsp->read_preprocess) {
  12. status = dsp->base.upstream->vtbl->read_frame(dsp->base.upstream, frame);
  13. if (status != APR_SUCCESS)
  14. return status;
  15. speex_preprocess_run(dsp->read_preprocess, (spx_int16_t*)&frame->buffer[0]);
  16. } else {
  17. status = dsp->base.upstream->vtbl->read_frame(dsp->base.upstream, frame);
  18. }
  19. return status;
  20. }
  21. static apr_status_t write_frame(void *self, const audioframe_t *frame)
  22. {
  23. audiodsp_t *dsp = CONTAINING_RECORD(self, audiodsp_t, base);
  24. apr_status_t status;
  25. if (dsp->write_preprocess) {
  26. dsp->tmp_write_frame.size = SUGGEST_FRAME_SIZE;
  27. audioframe_copy(&dsp->tmp_write_frame, frame);
  28. speex_preprocess_run(dsp->write_preprocess, (spx_int16_t*)dsp->tmp_write_frame.buffer);
  29. status = dsp->base.upstream->vtbl->write_frame(dsp->base.upstream, &dsp->tmp_write_frame);
  30. } else {
  31. status = dsp->base.upstream->vtbl->write_frame(dsp->base.upstream, frame);
  32. }
  33. return status;
  34. }
  35. static audiostream_vtbl_t g_stream_vtbl = {
  36. &read_frame,
  37. &write_frame,
  38. };
  39. apr_status_t audiodsp_create(apr_pool_t *pool,
  40. audioengine_t *engine,
  41. int read_opt,
  42. int write_opt,
  43. int clock,
  44. audiodsp_t **p_dsp)
  45. {
  46. audiodsp_t *dsp;
  47. dsp = apr_palloc(pool, sizeof(audiodsp_t));
  48. audiostream_init(engine, &g_stream_vtbl, &dsp->base);
  49. dsp->base.direction = STREAM_DIR_BOTH;
  50. dsp->clock = clock;
  51. dsp->read_option = read_opt;
  52. dsp->write_option = write_opt;
  53. dsp->frame_samples = FRAME_TIME * clock / 1000;
  54. dsp->tmp_read_frame.size = SUGGEST_FRAME_SIZE;
  55. dsp->tmp_read_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  56. dsp->tmp_write_frame.size = SUGGEST_FRAME_SIZE;
  57. dsp->tmp_write_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  58. dsp->read_preprocess = NULL;
  59. dsp->write_preprocess = NULL;
  60. if (read_opt) {
  61. int disabled = 0;
  62. int enabled = 1;
  63. dsp->read_preprocess = speex_preprocess_state_init(dsp->frame_samples, clock);
  64. speex_preprocess_ctl(dsp->read_preprocess, SPEEX_PREPROCESS_SET_AGC,
  65. read_opt & AUDIO_DSP_AGC ? &enabled : &disabled);
  66. speex_preprocess_ctl(dsp->read_preprocess, SPEEX_PREPROCESS_SET_DENOISE,
  67. read_opt & AUDIO_DSP_DENOISE ? &enabled : &disabled);
  68. }
  69. if (write_opt) {
  70. int disabled = 0;
  71. int enabled = 1;
  72. dsp->write_preprocess = speex_preprocess_state_init(dsp->frame_samples,clock);
  73. speex_preprocess_ctl(dsp->write_preprocess, SPEEX_PREPROCESS_SET_AGC,
  74. write_opt & AUDIO_DSP_AGC ? &enabled : &disabled);
  75. speex_preprocess_ctl(dsp->write_preprocess, SPEEX_PREPROCESS_SET_DENOISE,
  76. write_opt & AUDIO_DSP_DENOISE ? &enabled : &disabled);
  77. }
  78. *p_dsp = dsp;
  79. return APR_SUCCESS;
  80. }
  81. void audiodsp_destroy(audiodsp_t *dsp)
  82. {
  83. if (dsp->read_preprocess) {
  84. speex_preprocess_state_destroy(dsp->read_preprocess);
  85. dsp->read_preprocess = NULL;
  86. }
  87. if (dsp->write_preprocess) {
  88. speex_preprocess_state_destroy(dsp->write_preprocess);
  89. dsp->write_preprocess = NULL;
  90. }
  91. }