audio_ll_drv.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include "user.h"
  2. enum
  3. {
  4. AUDIO_STATE_IDLE,
  5. AUDIO_STATE_NEED_DATA,
  6. AUDIO_STATE_WAIT_PAUSE,
  7. AUDIO_STATE_PAUSE,
  8. };
  9. typedef struct
  10. {
  11. llist_head Node;
  12. PV_Union uPV;
  13. uint32_t Len;
  14. }Audio_DataBlockStruct;
  15. typedef struct
  16. {
  17. uint32_t DACOutRMode;
  18. uint8_t DACBit;
  19. }Audio_CtrlStruct;
  20. static Audio_CtrlStruct prvAudio;
  21. static int32_t prvAudio_DACCB(void *pData, void *pParam)
  22. {
  23. Audio_StreamStruct *pStream = (Audio_StreamStruct *)pParam;
  24. Audio_DataBlockStruct *OldBlock, *NewBlock;
  25. OldBlock = (Audio_DataBlockStruct *)pStream->DataHead.next;
  26. llist_del(&OldBlock->Node);
  27. if (!llist_empty(&pStream->DataHead) && !pStream->IsPause)
  28. {
  29. NewBlock = (Audio_DataBlockStruct *)pStream->DataHead.next;
  30. DAC_Send(pStream->BusID, NewBlock->uPV.pu16, NewBlock->Len, prvAudio_DACCB, pParam);
  31. pStream->IsHardwareRun = 1;
  32. }
  33. free(OldBlock->uPV.pu8);
  34. free(OldBlock);
  35. pStream->CB(pStream, NULL);
  36. if (llist_empty(&pStream->DataHead))
  37. {
  38. pStream->IsHardwareRun = 0;
  39. pStream->CB(pStream, INVALID_HANDLE_VALUE);
  40. }
  41. else if (!pStream->IsPause)
  42. {
  43. if (!pStream->IsHardwareRun)
  44. {
  45. NewBlock = (Audio_DataBlockStruct *)pStream->DataHead.next;
  46. DAC_Send(pStream->BusID, NewBlock->uPV.pu16, NewBlock->Len, prvAudio_DACCB, pParam);
  47. pStream->IsHardwareRun = 1;
  48. }
  49. }
  50. else
  51. {
  52. pStream->IsHardwareRun = 0;
  53. }
  54. return 0;
  55. }
  56. void Audio_GlobalInit(void)
  57. {
  58. prvAudio.DACOutRMode = 1;
  59. prvAudio.DACBit = 10;
  60. }
  61. int32_t Audio_StartRaw(Audio_StreamStruct *pStream)
  62. {
  63. INIT_LLIST_HEAD(&pStream->DataHead);
  64. if (pStream->BitDepth > 16) return -ERROR_PARAM_INVALID;
  65. if (pStream->BitDepth < 8) return -ERROR_PARAM_INVALID;
  66. switch(pStream->Format)
  67. {
  68. case AUSTREAM_FORMAT_PCM:
  69. break;
  70. default:
  71. return -ERROR_PARAM_INVALID;
  72. }
  73. switch(pStream->BusType)
  74. {
  75. case AUSTREAM_BUS_DAC:
  76. DAC_ForceStop(pStream->BusID);
  77. DAC_DMAInit(0, DAC_TX_DMA_STREAM);
  78. DAC_Setup(pStream->BusID, pStream->SampleRate, prvAudio.DACOutRMode);
  79. pStream->IsHardwareRun = 0;
  80. pStream->IsPause = 0;
  81. break;
  82. default:
  83. return -ERROR_PARAM_INVALID;
  84. }
  85. return ERROR_NONE;
  86. }
  87. static int32_t prvAudio_RunDAC(Audio_StreamStruct *pStream)
  88. {
  89. Audio_DataBlockStruct *Block = (Audio_DataBlockStruct *)pStream->DataHead.next;
  90. if (llist_empty(&pStream->DataHead))
  91. {
  92. pStream->CB(pStream, NULL);
  93. }
  94. else
  95. {
  96. Block = (Audio_DataBlockStruct *)pStream->DataHead.next;
  97. DAC_Send(pStream->BusID, Block->uPV.pu16, Block->Len, prvAudio_DACCB, pStream);
  98. pStream->IsHardwareRun = 1;
  99. }
  100. return ERROR_NONE;
  101. }
  102. static int32_t prvAudio_WriteDACRaw(Audio_StreamStruct *pStream, uint8_t *pByteData, uint32_t ByteLen, uint8_t AddHead)
  103. {
  104. uint32_t i, VaildLen;
  105. uint32_t DiffBit;
  106. uint16_t *wTemp;
  107. Audio_DataBlockStruct *Block = zalloc(sizeof(Audio_DataBlockStruct));
  108. VaildLen = ByteLen >> (pStream->ChannelCount >> 1);
  109. //DBG("%u,%u", ByteLen, VaildLen);
  110. if (pStream->BitDepth > 8)
  111. {
  112. Block->uPV.pu8 = malloc(VaildLen);
  113. if (!Block->uPV.pu8)
  114. {
  115. free(Block);
  116. DBG("no mem!, %u,%u", ByteLen, VaildLen);
  117. return -ERROR_NO_MEMORY;
  118. }
  119. Block->Len = VaildLen >> 1;
  120. if (2 == pStream->ChannelCount)
  121. {
  122. wTemp = pByteData;
  123. for(i = 0; i < Block->Len; i++)
  124. {
  125. Block->uPV.pu16[i] = wTemp[i * 2];
  126. }
  127. }
  128. else
  129. {
  130. memcpy(Block->uPV.pu8, pByteData, VaildLen);
  131. }
  132. if (pStream->IsDataSigned)
  133. {
  134. for(i = 0; i < Block->Len; i++)
  135. {
  136. Block->uPV.pu16[i] += 0x8000;
  137. }
  138. }
  139. if (pStream->BitDepth >= prvAudio.DACBit)
  140. {
  141. DiffBit = pStream->BitDepth - prvAudio.DACBit;
  142. for(i = 0; i < Block->Len; i++)
  143. {
  144. Block->uPV.pu16[i] = Block->uPV.pu16[i] >> DiffBit;
  145. }
  146. }
  147. else
  148. {
  149. DiffBit = prvAudio.DACBit - pStream->BitDepth;
  150. for(i = 0; i < Block->Len; i++)
  151. {
  152. Block->uPV.pu16[i] = Block->uPV.pu16[i] << DiffBit;
  153. }
  154. }
  155. }
  156. else
  157. {
  158. Block->uPV.pu8 = malloc(VaildLen * 2);
  159. if (!Block->uPV.pu8)
  160. {
  161. free(Block);
  162. DBG("no mem!, %u,%u", ByteLen, VaildLen);
  163. return -ERROR_NO_MEMORY;
  164. }
  165. Block->Len = VaildLen;
  166. DiffBit = prvAudio.DACBit - 8;
  167. if (pStream->IsDataSigned)
  168. {
  169. for(i = 0; i < Block->Len; i++)
  170. {
  171. Block->uPV.pu16[i] = ((pByteData[i * pStream->ChannelCount] + 0x80) & 0x00ff);
  172. Block->uPV.pu16[i] <<= DiffBit;
  173. }
  174. }
  175. else
  176. {
  177. for(i = 0; i < Block->Len; i++)
  178. {
  179. Block->uPV.pu16[i] = pByteData[i * pStream->ChannelCount];
  180. Block->uPV.pu16[i] <<= DiffBit;
  181. }
  182. }
  183. }
  184. uint32_t Critical;
  185. Critical = OS_EnterCritical();
  186. if (AddHead)
  187. {
  188. llist_add(&Block->Node, &pStream->DataHead);
  189. }
  190. else
  191. {
  192. llist_add_tail(&Block->Node, &pStream->DataHead);
  193. }
  194. OS_ExitCritical(Critical);
  195. if (!pStream->IsHardwareRun && !pStream->IsPause)
  196. {
  197. return prvAudio_RunDAC(pStream);
  198. }
  199. return ERROR_NONE;
  200. }
  201. int32_t Audio_WriteRaw(Audio_StreamStruct *pStream, uint8_t *pByteData, uint32_t ByteLen, uint8_t AddHead)
  202. {
  203. if (!ByteLen) {return -ERROR_PARAM_INVALID;}
  204. switch(pStream->BusType)
  205. {
  206. case AUSTREAM_BUS_DAC:
  207. return prvAudio_WriteDACRaw(pStream, pByteData, ByteLen, AddHead);
  208. default:
  209. return -ERROR_PARAM_INVALID;
  210. }
  211. }
  212. static int32_t prvAudio_DeleteData(void *pData, void *pParam)
  213. {
  214. Buffer_Struct *UriBuf = (Buffer_Struct *)pParam;
  215. Audio_DataBlockStruct *Block = (Audio_DataBlockStruct *)pData;
  216. free(Block->uPV.p);
  217. return LIST_DEL;
  218. }
  219. void Audio_Stop(Audio_StreamStruct *pStream)
  220. {
  221. switch(pStream->BusType)
  222. {
  223. case AUSTREAM_BUS_DAC:
  224. DAC_Stop(pStream->BusID);
  225. llist_traversal(&pStream->DataHead, prvAudio_DeleteData, NULL);
  226. break;
  227. default:
  228. return;
  229. }
  230. }
  231. void Audio_Pause(Audio_StreamStruct *pStream)
  232. {
  233. pStream->IsPause = 1;
  234. }
  235. void Audio_Resume(Audio_StreamStruct *pStream)
  236. {
  237. pStream->IsPause = 0;
  238. if (!pStream->IsHardwareRun)
  239. {
  240. switch(pStream->BusType)
  241. {
  242. case AUSTREAM_BUS_DAC:
  243. prvAudio_RunDAC(pStream);
  244. break;
  245. default:
  246. return;
  247. }
  248. }
  249. }
  250. #ifdef __BUILD_APP__
  251. INIT_DRV_EXPORT(Audio_GlobalInit, "0");
  252. #endif