audiocodec.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include "precompile.h"
  2. #include "audiocodec.h"
  3. #include "audiocontext.h"
  4. #include "other/wsola.h"
  5. #include "codec/codecmgr.h"
  6. #include "codec/g711codec.h"
  7. #ifdef _WIN32
  8. #include "codec/g729acodec.h"
  9. #endif // _WIN32
  10. #include <assert.h>
  11. static apr_status_t read_frame(void *self, audioframe_t *frame)
  12. {
  13. audiocodec_t *codec = CONTAINING_RECORD(self, audiocodec_t, base);
  14. codec_t *private_codec = codec->private_codec;
  15. apr_status_t status;
  16. if (codec->base.downstream == NULL) {
  17. if (codec->flag & AUDIO_CODEC_OPT_DECODE_READ) {
  18. frame->size = codec->ptime * 2 * codec->clock / 1000;
  19. memset(frame->buffer, 0, frame->size);
  20. return APR_SUCCESS;
  21. } else {
  22. return APR_EGENERAL;
  23. }
  24. }
  25. codec->tmp_frame.size = SUGGEST_FRAME_SIZE;
  26. status = codec->base.downstream->vtbl->read_frame(codec->base.downstream,
  27. &codec->tmp_frame);
  28. if (status != APR_SUCCESS) {
  29. if (codec->flag & AUDIO_CODEC_OPT_DECODE_READ) {
  30. if (codec->flag&AUDIO_CODEC_OPT_PLC && codec->last_plc) {
  31. wsola_generate(codec->plc_state, (short*)frame->buffer);
  32. frame->size = codec->ptime * 2 * codec->clock / 1000;
  33. codec->last_plc--;
  34. } else {
  35. frame->size = codec->ptime * 2 * codec->clock / 1000;
  36. memset(frame->buffer, 0, frame->size);
  37. }
  38. return APR_SUCCESS;
  39. }
  40. } else {
  41. if (codec->flag & AUDIO_CODEC_OPT_ENCODE_READ) {
  42. status = private_codec->factory->encode(private_codec,
  43. codec->tmp_frame.buffer, codec->tmp_frame.size,
  44. frame->buffer, &frame->size);
  45. if (status != APR_SUCCESS || frame->size == 0) {
  46. frame->size = codec->ptime * 2 * codec->clock / 1000;
  47. memset(frame->buffer, 0, frame->size);
  48. status = APR_SUCCESS;
  49. }
  50. } else {
  51. status = private_codec->factory->decode(private_codec,
  52. codec->tmp_frame.buffer, codec->tmp_frame.size,
  53. frame->buffer, &frame->size);
  54. if (status != APR_SUCCESS || frame->size == 0) {
  55. frame->size = codec->ptime * 2 * codec->clock / 1000;
  56. memset(frame->buffer, 0, frame->size);
  57. status = APR_SUCCESS;
  58. }
  59. if (status == APR_SUCCESS && codec->flag&AUDIO_CODEC_OPT_PLC) {
  60. wsola_save(codec->plc_state, (short*)frame->buffer, 0);
  61. codec->last_plc = 1;
  62. }
  63. }
  64. }
  65. return status;
  66. }
  67. static apr_status_t write_frame(void *self, const audioframe_t *frame)
  68. {
  69. audiocodec_t *codec = CONTAINING_RECORD(self, audiocodec_t, base);
  70. codec_t *private_codec = codec->private_codec;
  71. apr_status_t status;
  72. if (codec->base.downstream == NULL)
  73. return APR_EGENERAL;
  74. codec->tmp_frame.size = SUGGEST_FRAME_SIZE;
  75. codec->tmp_frame.dtmf = frame->dtmf;
  76. if (codec->flag & AUDIO_CODEC_OPT_ENCODE_READ) {
  77. status = private_codec->factory->decode(private_codec,
  78. frame->buffer, frame->size,
  79. codec->tmp_frame.buffer, &codec->tmp_frame.size);
  80. } else {
  81. status = private_codec->factory->encode(private_codec,
  82. frame->buffer, frame->size,
  83. codec->tmp_frame.buffer, &codec->tmp_frame.size);
  84. }
  85. if (status == APR_SUCCESS) {
  86. status = codec->base.downstream->vtbl->write_frame(codec->base.downstream,
  87. &codec->tmp_frame);
  88. }
  89. return status;
  90. }
  91. static audiostream_vtbl_t g_stream_vtbl = {
  92. &read_frame,
  93. &write_frame,
  94. };
  95. apr_status_t audiocodec_create(apr_pool_t *pool,
  96. audioengine_t *engine,
  97. const char *name,
  98. int clock,
  99. int ptime,
  100. int flag,
  101. audiocodec_t**p_codec)
  102. {
  103. audiocodec_t *codec;
  104. codec_factory_t *factory;
  105. factory = codec_factory_find(name);
  106. if (!factory)
  107. return APR_NOTFOUND;
  108. codec = apr_palloc(pool, sizeof(audiocodec_t));
  109. codec->private_codec = factory->create(pool, clock, ptime);
  110. if (!codec->private_codec) {
  111. return APR_EGENERAL;
  112. }
  113. codec->ptime = ptime;
  114. codec->clock = clock;
  115. audiostream_init(engine, &g_stream_vtbl, &codec->base);
  116. codec->base.direction = STREAM_DIR_BOTH;
  117. codec->tmp_frame.size = SUGGEST_FRAME_SIZE;
  118. codec->tmp_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  119. codec->tmp_frame.dtmf = 0;
  120. codec->flag = flag;
  121. codec->last_plc = 0;
  122. wsola_create(clock, ptime * clock / 1000, 1, WSOLA_NO_FADING, (wsola_t**)&codec->plc_state);
  123. *p_codec = codec;
  124. return APR_SUCCESS;
  125. }
  126. apr_status_t audiocodec_set_param(audiocodec_t *codec, const char *key, const char *value)
  127. {
  128. codec_t *private_codec = codec->private_codec;
  129. return private_codec->factory->set_param(private_codec, key, value);
  130. }
  131. apr_status_t audiocodec_get_param(audiocodec_t *codec, const char *key, char *value)
  132. {
  133. codec_t *private_codec = codec->private_codec;
  134. return private_codec->factory->get_param(private_codec, key, value);
  135. }
  136. apr_status_t audiocodec_init(audiocodec_t *codec)
  137. {
  138. codec_t *private_codec = codec->private_codec;
  139. return private_codec->factory->init(private_codec);
  140. }
  141. apr_status_t audiocodec_term(audiocodec_t *codec)
  142. {
  143. codec_t *private_codec = codec->private_codec;
  144. return private_codec->factory->term(private_codec);
  145. }
  146. void audiocodec_destroy(audiocodec_t *codec)
  147. {
  148. codec_t *private_codec = codec->private_codec;
  149. private_codec->factory->destroy(private_codec);
  150. wsola_destroy(codec->plc_state);
  151. codec->plc_state = NULL;
  152. }
  153. apr_status_t audiocodec_pcma_decode(const void *inbuf,int insize,void *outbuf,int *outsize)
  154. {
  155. return pcma_codec_decode(inbuf, insize, outbuf, outsize);
  156. }
  157. apr_status_t audiocodec_pcmu_decode(const void *inbuf,int insize,void *outbuf,int *outsize)
  158. {
  159. return pcmu_codec_decode(inbuf, insize, outbuf, outsize);
  160. }
  161. apr_status_t audiocodec_g729a_decode(const void *inbuf,int insize,void *outbuf,int *outsize)
  162. {
  163. #ifdef _WIN32
  164. return audio_g729a_codec_decode(inbuf, insize, outbuf, outsize);
  165. #else
  166. return 0;
  167. #endif // _WIN32
  168. }