audio_codec_clock.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*****************************************************************
  2. >file name : audio_codec_clock.c
  3. >create time : Thu 03 Jun 2021 09:36:12 AM CST
  4. *****************************************************************/
  5. #define LOG_TAG "[CODEC_CLK]"
  6. #define LOG_INFO_ENABLE
  7. #define LOG_DEBUG_ENABLE
  8. #define LOG_DUMP_ENABLE
  9. #define LOG_ERROR_ENABLE
  10. #define LOG_WARN_ENABLE
  11. #include "debug.h"
  12. #include "app_config.h"
  13. #include "system/includes.h"
  14. #include "audio_codec_clock.h"
  15. #define AUDIO_CODING_ALL (0xffffffff)
  16. #define MAX_CODING_TYPE_NUM 5 //可根据模式的解码格式需求扩展
  17. #define AUDIO_CODEC_BASE_CLK SYS_96M
  18. static LIST_HEAD(codec_clock_head);
  19. struct audio_codec_clock {
  20. u32 coding_type;
  21. u32 clk;
  22. };
  23. struct audio_codec_clk_context {
  24. u8 mode;
  25. struct audio_codec_clock params;
  26. struct list_head entry;
  27. };
  28. const struct audio_codec_clock audio_clock[AUDIO_MAX_MODE][MAX_CODING_TYPE_NUM] = {
  29. {
  30. //A2DP_MODE
  31. {
  32. AUDIO_CODING_SBC,
  33. #if (TCFG_BT_MUSIC_EQ_ENABLE && ((EQ_SECTION_MAX >= 10) && AUDIO_OUT_EFFECT_ENABLE)) || (AUDIO_VBASS_CONFIG || AUDIO_SURROUND_CONFIG)
  34. SYS_64M,
  35. #elif (TCFG_BT_MUSIC_EQ_ENABLE && ((EQ_SECTION_MAX >= 10) || AUDIO_OUT_EFFECT_ENABLE))
  36. #if A2DP_AUDIO_PLC_ENABLE
  37. SYS_64M,
  38. #else
  39. SYS_48M,
  40. #endif
  41. #else
  42. #if (TCFG_AUDIO_ANC_ENABLE)
  43. SYS_24M,
  44. #else
  45. SYS_48M,
  46. #endif
  47. #endif
  48. },
  49. {
  50. AUDIO_CODING_AAC,
  51. #if (TCFG_BT_MUSIC_EQ_ENABLE && ((EQ_SECTION_MAX >= 10) || AUDIO_OUT_EFFECT_ENABLE)) | (AUDIO_VBASS_CONFIG || AUDIO_SURROUND_CONFIG)
  52. SYS_64M,
  53. #else
  54. SYS_48M,
  55. #endif
  56. }
  57. },
  58. {
  59. //ESCO MODE
  60. {AUDIO_CODING_MSBC, 0},
  61. {AUDIO_CODING_CVSD, 0},
  62. },
  63. {
  64. //TONE MODE
  65. {AUDIO_CODING_AAC, SYS_64M},
  66. {AUDIO_CODING_WAV | AUDIO_CODING_MP3, 96 * 1000000L},
  67. {AUDIO_CODING_ALL, 0},
  68. },
  69. {
  70. //MIC2PCM MODE
  71. {AUDIO_CODING_PCM, SYS_48M},
  72. },
  73. {
  74. //KWS MODE
  75. {AUDIO_CODING_ALL, SYS_48M},
  76. },
  77. //TODO
  78. };
  79. int audio_codec_clock_set(u8 mode, u32 coding_type, u8 preemption)
  80. {
  81. struct audio_codec_clk_context *ctx = (struct audio_codec_clk_context *)zalloc(sizeof(struct audio_codec_clk_context));
  82. u32 new_clk = 0;
  83. if (mode >= MAX_CODING_TYPE_NUM) {
  84. log_error("Not support this mode : %d", mode);
  85. return -EINVAL;
  86. }
  87. const struct audio_codec_clock *params = audio_clock[mode];
  88. int i = 0;
  89. for (i = 0; i < MAX_CODING_TYPE_NUM; i++) {
  90. if (params[i].coding_type & coding_type) {
  91. goto match_clock;
  92. }
  93. }
  94. log_error("Not found right coding type : %d", coding_type);
  95. return -EINVAL;
  96. match_clock:
  97. new_clk = params[i].clk ? params[i].clk : clk_get("sys");
  98. if (!preemption) {
  99. struct audio_codec_clk_context *ctx1;
  100. if (!list_empty(&codec_clock_head)) {
  101. ctx1 = list_first_entry(&codec_clock_head, struct audio_codec_clk_context, entry);
  102. if (ctx1 && new_clk <= ctx1->params.clk) {
  103. /*叠加解码的时钟不可小于在播放的音频时钟*/
  104. new_clk = ctx1->params.clk + 12 * 1000000;
  105. }
  106. }
  107. }
  108. ctx->mode = mode;
  109. ctx->params.coding_type = coding_type;
  110. ctx->params.clk = new_clk;
  111. clk_set("sys", new_clk);
  112. list_add(&ctx->entry, &codec_clock_head);
  113. return 0;
  114. }
  115. void audio_codec_clock_del(u8 mode)
  116. {
  117. struct audio_codec_clk_context *ctx;
  118. u32 next_clk = 0;
  119. list_for_each_entry(ctx, &codec_clock_head, entry) {
  120. if (ctx->mode == mode) {
  121. goto clock_del;
  122. }
  123. }
  124. return;
  125. clock_del:
  126. list_del(&ctx->entry);
  127. free(ctx);
  128. if (!list_empty(&codec_clock_head)) {
  129. ctx = list_first_entry(&codec_clock_head, struct audio_codec_clk_context, entry);
  130. if (ctx) {
  131. next_clk = ctx->params.clk;
  132. }
  133. }
  134. if (!next_clk) {
  135. next_clk = AUDIO_CODEC_BASE_CLK;
  136. }
  137. clk_set("sys", next_clk);
  138. }