dsp_buffer.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c) 2020 Actions Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <mem_manager.h>
  7. #include "dsp_inner.h"
  8. #define MAX_SESSION_BUFF_NUM 20
  9. static struct dsp_session_buf buff_pool[MAX_SESSION_BUFF_NUM] __in_section_unique(DSP_SHARE_RAM);
  10. static int bit_mask = 0;
  11. static struct dsp_session_buf * malloc_session_buf(int size)
  12. {
  13. for (int i = 0 ; i < MAX_SESSION_BUFF_NUM; i++) {
  14. if (!(bit_mask & (1 << i))) {
  15. bit_mask |= (1 << i);
  16. memset(&buff_pool[i], 0, sizeof(struct dsp_session_buf));
  17. return &buff_pool[i];
  18. }
  19. }
  20. printk("session malloc failed\n");
  21. return NULL;
  22. }
  23. static void free_session_buf(struct dsp_session_buf * session_buf)
  24. {
  25. for (int i = 0 ; i < MAX_SESSION_BUFF_NUM; i++) {
  26. if (&buff_pool[i] == session_buf) {
  27. bit_mask &= (~(1 << i));
  28. return;
  29. }
  30. }
  31. }
  32. struct dsp_session_buf *dsp_session_buf_init(struct dsp_session *session,
  33. void *data, unsigned int size)
  34. {
  35. struct dsp_session_buf *buf = malloc_session_buf(sizeof(*buf));
  36. if (buf == NULL)
  37. return NULL;
  38. acts_ringbuf_init(&buf->buf, data, ACTS_RINGBUF_NELEM(size));
  39. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  40. buf->session = session;
  41. #endif
  42. return buf;
  43. }
  44. void dsp_session_buf_destroy(struct dsp_session_buf *buf)
  45. {
  46. if (buf)
  47. free_session_buf(buf);
  48. }
  49. struct dsp_session_buf *dsp_session_buf_alloc(struct dsp_session *session, unsigned int size)
  50. {
  51. struct dsp_session_buf *buf = malloc_session_buf(sizeof(*buf));
  52. if (buf == NULL)
  53. return NULL;
  54. void *data = mem_malloc(size);
  55. if (data == NULL) {
  56. mem_free(buf);
  57. return NULL;
  58. }
  59. acts_ringbuf_init(&buf->buf, data, ACTS_RINGBUF_NELEM(size));
  60. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  61. buf->session = session;
  62. #endif
  63. return buf;
  64. }
  65. void dsp_session_buf_free(struct dsp_session_buf *buf)
  66. {
  67. if (buf) {
  68. mem_free((void *)(buf->buf.cpu_ptr));
  69. free_session_buf(buf);
  70. }
  71. }
  72. void dsp_session_buf_reset(struct dsp_session_buf *buf)
  73. {
  74. acts_ringbuf_reset(&buf->buf);
  75. }
  76. unsigned int dsp_session_buf_size(struct dsp_session_buf *buf)
  77. {
  78. return ACTS_RINGBUF_SIZE8(acts_ringbuf_size(&buf->buf));
  79. }
  80. unsigned int dsp_session_buf_space(struct dsp_session_buf *buf)
  81. {
  82. return ACTS_RINGBUF_SIZE8(acts_ringbuf_space(&buf->buf));
  83. }
  84. unsigned int dsp_session_buf_length(struct dsp_session_buf *buf)
  85. {
  86. return ACTS_RINGBUF_SIZE8(acts_ringbuf_length(&buf->buf));
  87. }
  88. int dsp_session_buf_read(struct dsp_session_buf *buf, void *data, unsigned int size)
  89. {
  90. int len = ACTS_RINGBUF_SIZE8(acts_ringbuf_get(&buf->buf, data, ACTS_RINGBUF_NELEM(size)));
  91. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  92. /* Supposed next read the same size */
  93. //if (!k_is_in_isr() && dsp_session_buf_length(buf) < size) {
  94. // if (!dsp_session_kick(buf->session))
  95. // SYS_LOG_DBG("kick %u (%u ms)", dsp_session_buf_length(buf), k_uptime_get_32());
  96. //}
  97. #endif
  98. return len;
  99. }
  100. int dsp_session_buf_write(struct dsp_session_buf *buf, const void *data, unsigned int size)
  101. {
  102. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  103. bool empty = acts_ringbuf_is_empty(&buf->buf);
  104. #endif
  105. int len = ACTS_RINGBUF_SIZE8(acts_ringbuf_put(&buf->buf, data, ACTS_RINGBUF_NELEM(size)));
  106. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  107. /* Supposed next write the same size */
  108. if (!k_is_in_isr() && (empty || dsp_session_buf_space(buf) < size)) {
  109. if (!dsp_session_kick(buf->session))
  110. SYS_LOG_DBG("kick %u (%u ms)", dsp_session_buf_space(buf), k_uptime_get_32());
  111. }
  112. #endif
  113. return len;
  114. }
  115. int dsp_session_buf_read_to_buffer(struct dsp_session_buf *buf, void *buffer, unsigned int size)
  116. {
  117. int len = ACTS_RINGBUF_SIZE8(
  118. acts_ringbuf_read(&buf->buf, buffer, ACTS_RINGBUF_NELEM(size),
  119. NULL));
  120. return len;
  121. }
  122. int dsp_session_buf_read_to_stream(struct dsp_session_buf *buf,
  123. void *stream, unsigned int size,
  124. dsp_session_buf_write_fn stream_write)
  125. {
  126. int len = ACTS_RINGBUF_SIZE8(
  127. acts_ringbuf_read(&buf->buf, stream, ACTS_RINGBUF_NELEM(size),
  128. (acts_ringbuf_write_fn)stream_write));
  129. //printk("%s, read len 0x%x from dsp outbuf to outstream!\n\n", __func__, len);
  130. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  131. /* Supposed next read the same size */
  132. //if (!k_is_in_isr() && dsp_session_buf_length(buf) < size) {
  133. // if (!dsp_session_kick(buf->session))
  134. // SYS_LOG_DBG("kick %u (%u ms)", dsp_session_buf_length(buf), k_uptime_get_32());
  135. //}
  136. #endif
  137. return len;
  138. }
  139. int dsp_session_buf_write_from_buffer(struct dsp_session_buf *buf, void *buffer, unsigned int size)
  140. {
  141. int len = ACTS_RINGBUF_SIZE8(
  142. acts_ringbuf_write(&buf->buf, buffer, ACTS_RINGBUF_NELEM(size),
  143. NULL));
  144. //printk("%s: %d: write to dsp session in_buf: %p, len: 0x%x\n\n", __func__, __LINE__, buffer, len);
  145. return len;
  146. }
  147. int dsp_session_buf_write_from_stream(struct dsp_session_buf *buf,
  148. void *stream, unsigned int size,
  149. dsp_session_buf_read_fn stream_read)
  150. {
  151. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  152. bool empty = acts_ringbuf_is_empty(&buf->buf);
  153. #endif
  154. int len = ACTS_RINGBUF_SIZE8(
  155. acts_ringbuf_write(&buf->buf, stream, ACTS_RINGBUF_NELEM(size),
  156. (acts_ringbuf_read_fn)stream_read));
  157. //printk("%s, dsp session inbuf write 0x%x finish!\n\n", __func__, len);
  158. #if CONFIG_DSP_ACTIVE_POWER_LATENCY_MS >= 0
  159. /* Supposed next write the same size */
  160. if (!k_is_in_isr() && (empty || dsp_session_buf_space(buf) < size)) {
  161. if (!dsp_session_kick(buf->session))
  162. SYS_LOG_DBG("kick %u (%u ms)", dsp_session_buf_space(buf), k_uptime_get_32());
  163. }
  164. #endif
  165. return len;
  166. }
  167. size_t dsp_session_buf_drop_all(struct dsp_session_buf *buf)
  168. {
  169. return acts_ringbuf_drop_all(&buf->buf);
  170. }