audiocache.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "precompile.h"
  2. #include "audiocache.h"
  3. #include "audiocontext.h"
  4. #include "audiolog.h"
  5. static void process_frame(void *self)
  6. {
  7. apr_status_t status;
  8. audiocache_t *cache = CONTAINING_RECORD(self, audiocache_t, driver_base);
  9. if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_WRITE) {
  10. if (cache->pending_write.size != SUGGEST_FRAME_SIZE && cache->pending_write.size > 0) {
  11. status = cache->stream_base.vtbl->write_frame(cache->stream_base.downstream,
  12. &cache->pending_write);
  13. if (status != APR_SUCCESS) {
  14. audio_log_v(AUDIO_LOG_LEVEL_DEBUG,"audiostream write_frame failed, status = %d", status);
  15. }
  16. }
  17. }
  18. if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_READ) {
  19. cache->pending_read.size = SUGGEST_FRAME_SIZE;
  20. status = cache->stream_base.vtbl->read_frame(cache->stream_base.downstream,
  21. &cache->pending_read);
  22. if (status != APR_SUCCESS) {
  23. audio_log_v(AUDIO_LOG_LEVEL_DEBUG,"audiostream read_frame failed");
  24. }
  25. }
  26. }
  27. static apr_status_t read_frame(void *self, audioframe_t *frame)
  28. {
  29. apr_status_t status;
  30. audiocache_t *cache = CONTAINING_RECORD(self, audiocache_t, stream_base);
  31. if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_READ) {
  32. status = audioframe_copy(frame, &cache->pending_read);
  33. if (status != APR_SUCCESS) {
  34. audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audiostream_cached_read_frame failed, frm->size little than stream pending frame");
  35. }
  36. return status;
  37. }
  38. return APR_EGENERAL;
  39. }
  40. static apr_status_t write_frame(void *self, const audioframe_t *frame)
  41. {
  42. apr_status_t status;
  43. audiocache_t *cache = CONTAINING_RECORD(self, audiocache_t, stream_base);
  44. if (audiostream_get_direction(&cache->stream_base) & STREAM_DIR_WRITE) {
  45. cache->pending_write.size = SUGGEST_FRAME_SIZE;
  46. status = audioframe_copy(&cache->pending_write, frame);
  47. if (status != APR_SUCCESS) {
  48. audio_log_v(AUDIO_LOG_LEVEL_ERROR, "audiostream_cached_write_frame failed, frm->size larger than stream pending frame");
  49. return status;
  50. }
  51. }
  52. return APR_EGENERAL;
  53. }
  54. typedef struct audiostream_read_only {
  55. audiostream_t base;
  56. audiocache_t *cache;
  57. }audiostream_read_only;
  58. typedef struct audiostream_write_only {
  59. audiostream_t base;
  60. audiocache_t *cache;
  61. }audiostream_write_only;
  62. static apr_status_t istream_read_frame(void *self, audioframe_t *frame)
  63. {
  64. audiostream_read_only *ro = (audiostream_read_only *)self;
  65. audiocache_t *cache = ro->cache;
  66. return read_frame(&cache->stream_base, frame);
  67. }
  68. static apr_status_t ostream_write_frame(void *self, const audioframe_t *frame)
  69. {
  70. audiostream_write_only *wo = (audiostream_write_only *)self;
  71. audiocache_t *cache = wo->cache;
  72. return write_frame(&cache->stream_base, frame);
  73. }
  74. static audiodriver_vtbl_t g_driver_vtbl = {
  75. &process_frame,
  76. };
  77. static audiostream_vtbl_t g_stream_vtbl = {
  78. &read_frame,
  79. &write_frame,
  80. };
  81. static audiostream_vtbl_t g_istream_vtbl = {
  82. &istream_read_frame,
  83. NULL,
  84. };
  85. static audiostream_vtbl_t g_ostream_vtbl = {
  86. NULL,
  87. &ostream_write_frame,
  88. };
  89. apr_status_t audiocache_create(apr_pool_t *pool,
  90. audioengine_t *engine,
  91. int istream_cnt,
  92. int ostream_cnt,
  93. audiocache_t **p_cache)
  94. {
  95. audiocache_t *cache;
  96. int i;
  97. cache = apr_palloc(pool, sizeof(audiocache_t));
  98. cache->pending_read.size = SUGGEST_FRAME_SIZE;
  99. cache->pending_read.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  100. cache->pending_read.dtmf = 0;
  101. cache->pending_write.size = SUGGEST_FRAME_SIZE;
  102. cache->pending_write.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
  103. cache->pending_write.dtmf = 0;
  104. audiostream_init(engine, &g_stream_vtbl, &cache->stream_base);
  105. audiodriver_init(engine, &g_driver_vtbl, &cache->driver_base);
  106. cache->arr_istream = apr_array_make(pool, istream_cnt, sizeof(audiostream_read_only*));
  107. for (i = 0; i < istream_cnt; ++i) {
  108. audiostream_read_only *ro = apr_palloc(pool, sizeof(audiostream_read_only));
  109. audiostream_init(engine, &g_istream_vtbl, &ro->base);
  110. ro->base.direction = STREAM_DIR_READ;
  111. ro->cache = cache;
  112. APR_ARRAY_PUSH(cache->arr_istream, audiostream_read_only*) = ro;
  113. }
  114. cache->arr_ostream = apr_array_make(pool, ostream_cnt, sizeof(audiostream_write_only*));
  115. for (i = 0; i < ostream_cnt; ++i) {
  116. audiostream_write_only *wo = apr_palloc(pool, sizeof(audiostream_write_only));
  117. audiostream_init(engine, &g_ostream_vtbl, &wo->base);
  118. wo->base.direction = STREAM_DIR_WRITE;
  119. APR_ARRAY_PUSH(cache->arr_ostream, audiostream_write_only*) = wo;
  120. }
  121. *p_cache = cache;
  122. return APR_SUCCESS;
  123. }
  124. void audiocache_destroy(audiocache_t *cache)
  125. {
  126. }
  127. audiostream_t* audiocache_get_istream(audiocache_t *cache, int idx)
  128. {
  129. audiostream_read_only *ro = APR_ARRAY_IDX(cache->arr_istream, idx, audiostream_read_only *);
  130. return &ro->base;
  131. }
  132. audiostream_t* audiocache_get_ostream(audiocache_t *cache, int idx)
  133. {
  134. audiostream_write_only *wo = APR_ARRAY_IDX(cache->arr_ostream, idx, audiostream_write_only *);
  135. return &wo->base;
  136. }