audioresample.c 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "precompile.h"
  2. #include "audioresample.h"
  3. #include "audiolog.h"
  4. #include "audiocontext.h"
  5. #include <speex/speex_resampler.h>
  6. static apr_status_t read_frame(void *self, audioframe_t *frame)
  7. {
  8. apr_status_t status;
  9. audioresample_t *resample = CONTAINING_RECORD(self, audioresample_t, base);
  10. spx_uint32_t in_len;
  11. spx_uint32_t out_len;
  12. resample->read_resampled_frame.size = SUGGEST_FRAME_SIZE;
  13. status = resample->base.downstream->vtbl->read_frame(resample->base.downstream,
  14. &resample->read_resampled_frame);
  15. if (status != APR_SUCCESS)
  16. return status;
  17. in_len = (spx_uint32_t)resample->downstream_psize / 2;
  18. speex_resampler_process_int(resample->read_state, 0,
  19. (spx_int16_t*)&resample->read_resampled_frame.buffer[0], &in_len,
  20. (spx_int16_t*)&frame->buffer[0], &out_len);
  21. frame->size = out_len * 2;
  22. frame->dtmf = resample->read_resampled_frame.dtmf;
  23. return APR_SUCCESS;
  24. }
  25. static apr_status_t write_frame(void *self, const audioframe_t *frame)
  26. {
  27. apr_status_t status;
  28. audioresample_t *resample = CONTAINING_RECORD(self, audioresample_t, base);
  29. spx_uint32_t in_len;
  30. spx_uint32_t out_len;
  31. in_len = resample->upstream_psize / 2;
  32. speex_resampler_process_int(resample->write_state, 0,
  33. (spx_int16_t*)&frame->buffer[0], &in_len,
  34. (spx_int16_t*)&resample->write_resampled_frame.buffer[0], &out_len);
  35. resample->write_resampled_frame.size = out_len * 2;
  36. resample->write_resampled_frame.dtmf = frame->dtmf;
  37. status = resample->base.downstream->vtbl->write_frame(resample->base.downstream,
  38. &resample->write_resampled_frame);
  39. if (status != APR_SUCCESS)
  40. return status;
  41. return APR_SUCCESS;
  42. }
  43. static audiostream_vtbl_t g_stream_vtbl = {
  44. &read_frame,
  45. &write_frame,
  46. };
  47. apr_status_t audioresample_create(apr_pool_t *pool,
  48. audioengine_t *engine,
  49. int upstream_rate,
  50. int downstream_rate,
  51. int quality,
  52. audioresample_t **p_resample)
  53. {
  54. audioresample_t *resample;
  55. resample = apr_palloc(pool, sizeof(audioresample_t));
  56. audiostream_init(engine, &g_stream_vtbl, &resample->base);
  57. resample->base.direction = STREAM_DIR_BOTH;
  58. resample->quality = quality;
  59. resample->upstream_rate = upstream_rate;
  60. resample->downstream_rate = downstream_rate;
  61. resample->upstream_psize = 2 * FRAME_TIME * upstream_rate / 1000;
  62. resample->downstream_psize = 2 * FRAME_TIME * downstream_rate / 1000;
  63. resample->read_resampled_frame.size = SUGGEST_FRAME_SIZE;
  64. resample->read_resampled_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  65. resample->read_resampled_frame.dtmf = 0;
  66. resample->write_resampled_frame.size = SUGGEST_FRAME_SIZE;
  67. resample->write_resampled_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  68. resample->write_resampled_frame.dtmf = 0;
  69. resample->read_state = speex_resampler_init(1, downstream_rate, upstream_rate, quality, NULL);
  70. resample->write_state = speex_resampler_init(1, upstream_rate, downstream_rate, quality, NULL);
  71. *p_resample = resample;
  72. return APR_SUCCESS;
  73. }
  74. void audioresample_destroy(audioresample_t *resample)
  75. {
  76. speex_resampler_destroy(resample->read_state);
  77. speex_resampler_destroy(resample->write_state);
  78. }