pcm_decoder.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright (c) 2020, Actions Semi Co., Inc.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <errno.h>
  7. #include <as_audio_codec.h>
  8. #include <al_storage_io.h>
  9. #include <mem_manager.h>
  10. #include <linker/section_tags.h>
  11. #include <zephyr/types.h>
  12. #define PCM_FRAME_SIZE (64)
  13. /* consider 2 channels */
  14. #define GLOBAL_MEM_SIZE (PCM_FRAME_SIZE * sizeof(u16_t))
  15. #define EXPORT_GLOBAL_MEM
  16. #ifndef EXPORT_GLOBAL_MEM
  17. static u16_t pcm_decoder_global_bss[GLOBAL_MEM_SIZE / sizeof(u16_t)] _NODATA_SECTION(.decoder_pcm_bss);
  18. #endif
  19. struct pcm_decoder {
  20. u16_t frame_bytes;
  21. u16_t remain_bytes;
  22. u16_t *pcm[2];
  23. u8_t channels;
  24. storage_io_t *storage_io;
  25. };
  26. static int _as_decoder_ops_pcm_close(void *hnd)
  27. {
  28. if (hnd)
  29. mem_free(hnd);
  30. return AD_RET_OK;
  31. }
  32. static int _as_decoder_ops_pcm_open(void **hnd, as_dec_t *as_dec)
  33. {
  34. struct pcm_decoder *decoder = NULL;
  35. u16_t *global_mem = NULL;
  36. if (as_dec->channels != 1 && as_dec->channels != 2)
  37. return AD_RET_UNEXPECTED;
  38. #ifdef EXPORT_GLOBAL_MEM
  39. if(as_dec->channels == 1) {
  40. if (as_dec->global_buf_len[0] < GLOBAL_MEM_SIZE)
  41. return AD_RET_UNEXPECTED;
  42. } else {
  43. if (as_dec->global_buf_len[0] < GLOBAL_MEM_SIZE * 3)
  44. return AD_RET_UNEXPECTED;
  45. }
  46. global_mem = as_dec->global_buf_addr[0];
  47. #else
  48. global_mem = pcm_decoder_global_bss;
  49. #endif
  50. decoder = mem_malloc(sizeof(*decoder));
  51. if (!decoder)
  52. return AD_RET_OUTOFMEMORY;
  53. decoder->storage_io = as_dec->storage_io;
  54. decoder->frame_bytes = PCM_FRAME_SIZE * sizeof(u16_t) * as_dec->channels;
  55. decoder->remain_bytes = 0;
  56. decoder->channels = as_dec->channels;
  57. decoder->pcm[0] = global_mem;
  58. decoder->pcm[1] = (decoder->channels > 1) ?
  59. (decoder->pcm[0] + PCM_FRAME_SIZE * 2) : NULL;
  60. *hnd = (void *)decoder;
  61. return AD_RET_OK;
  62. }
  63. static int _as_decoder_ops_pcm_decode(void *hnd, as_decode_info_t *decode_info)
  64. {
  65. struct pcm_decoder *decoder = hnd;
  66. u8_t *pcmbuf = (u8_t *)decoder->pcm[0] + decoder->remain_bytes;
  67. int len = decoder->frame_bytes - decoder->remain_bytes;
  68. len = decoder->storage_io->read(pcmbuf, 1, len, decoder->storage_io);
  69. if (len <= 0)
  70. return AD_RET_DATAUNDERFLOW;
  71. decoder->remain_bytes += len;
  72. if ((decoder->remain_bytes < decoder->frame_bytes)
  73. && (decoder->storage_io->tell(decoder->storage_io, STORAGEIO_TELL_END) == 0)) {
  74. return AD_RET_DATAUNDERFLOW;
  75. }
  76. if (decoder->channels > 1) {
  77. u16_t *pcm_l = decoder->pcm[0];
  78. u16_t *pcm_r = decoder->pcm[1];
  79. u16_t *pcm_beg = pcm_l;
  80. u16_t *pcm_end = pcm_l + decoder->remain_bytes / 2;
  81. while (pcm_beg < pcm_end) {
  82. *pcm_l++ = *pcm_beg++;
  83. *pcm_r++ = *pcm_beg++;
  84. }
  85. }
  86. decode_info->aout->pcm[0] = decoder->pcm[0];
  87. decode_info->aout->pcm[1] = decoder->pcm[1];
  88. decode_info->aout->channels = decoder->channels;
  89. decode_info->aout->samples = decoder->remain_bytes / decoder->channels / 2;
  90. decode_info->aout->sample_bits = 16;
  91. decode_info->aout->frac_bits = 0;
  92. decoder->remain_bytes = 0;
  93. return AD_RET_OK;
  94. }
  95. static int _as_decoder_ops_pcm_mem_require(void *hnd, as_mem_info_t *mem_info)
  96. {
  97. #ifdef EXPORT_GLOBAL_MEM
  98. as_dec_t *as_dec = (as_dec_t*)mem_info->param;
  99. if(as_dec->channels == 1)
  100. mem_info->global_buf_len[0] = GLOBAL_MEM_SIZE;
  101. else
  102. mem_info->global_buf_len[0] = GLOBAL_MEM_SIZE * 3;
  103. #else
  104. mem_info->global_buf_len[0] = 0;
  105. #endif
  106. mem_info->share_buf_len[0] = 0;
  107. return AD_RET_OK;
  108. }
  109. int as_decoder_ops_pcm(void *hnd, asdec_ex_ops_cmd_t cmd, unsigned int args)
  110. {
  111. switch (cmd) {
  112. case AD_CMD_OPEN:
  113. return _as_decoder_ops_pcm_open((void **)hnd, (as_dec_t *)args);
  114. case AD_CMD_CLOSE:
  115. return _as_decoder_ops_pcm_close(hnd);
  116. case AD_CMD_FRAME_DECODE:
  117. return _as_decoder_ops_pcm_decode(hnd, (as_decode_info_t *)args);
  118. case AD_CMD_MEM_REQUIRE:
  119. return _as_decoder_ops_pcm_mem_require(hnd, (as_mem_info_t *)args);
  120. default:
  121. return AD_RET_OK;
  122. }
  123. }