audio.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. #include "FreeRTOS.h"
  2. #include "chip.h"
  3. #include "audio.h"
  4. enum
  5. {
  6. REPLAY_EVT_NONE = 0x00,
  7. REPLAY_EVT_START = 0x01,
  8. REPLAY_EVT_STOP = 0x02,
  9. };
  10. struct audio_queue_data
  11. {
  12. uint8_t *data;
  13. int size;
  14. };
  15. struct audio_device *audio_dev[2] = {NULL, NULL};
  16. static int audio_send_replay_frame(struct audio_device *audio)
  17. {
  18. int result = 0;
  19. uint8_t *data;
  20. size_t dst_size, src_size;
  21. uint16_t position, remain_bytes = 0, index = 0;
  22. struct audio_buf_info *buf_info;
  23. struct audio_queue_data qdata;
  24. configASSERT(audio != NULL);
  25. buf_info = &audio->replay->buf_info;
  26. /* save current pos */
  27. position = audio->replay->pos;
  28. dst_size = buf_info->block_size;
  29. /* check replay queue is empty */
  30. if (xQueueIsQueueEmptyFromISR(audio->replay->queue) == pdTRUE)
  31. {
  32. /* ack stop event */
  33. if (audio->replay->event & REPLAY_EVT_STOP) {
  34. xQueueSendFromISR(audio->replay->cmp, NULL, 0);
  35. return 0;
  36. }
  37. /* send zero frames */
  38. memset(&buf_info->buffer[audio->replay->pos], 0, dst_size);
  39. audio->replay->pos += dst_size;
  40. audio->replay->pos %= buf_info->total_size;
  41. }
  42. else
  43. {
  44. memset(&buf_info->buffer[audio->replay->pos], 0, dst_size);
  45. /* copy data from memory pool to hardware device fifo */
  46. while (index < dst_size)
  47. {
  48. result = xQueuePeekFromISR(audio->replay->queue, &qdata);
  49. if (result != pdTRUE)
  50. {
  51. TRACE_DEBUG("under run %d, remain %d", audio->replay->pos, remain_bytes);
  52. audio->replay->pos -= remain_bytes;
  53. audio->replay->pos += dst_size;
  54. audio->replay->pos %= buf_info->total_size;
  55. audio->replay->read_index = 0;
  56. result = -1;
  57. break;
  58. }
  59. data = qdata.data;
  60. src_size = qdata.size;
  61. remain_bytes = configMIN((dst_size - index), (src_size - audio->replay->read_index));
  62. memcpy(&buf_info->buffer[audio->replay->pos],
  63. &data[audio->replay->read_index], remain_bytes);
  64. index += remain_bytes;
  65. audio->replay->read_index += remain_bytes;
  66. audio->replay->pos += remain_bytes;
  67. audio->replay->pos %= buf_info->total_size;
  68. if (audio->replay->read_index == src_size)
  69. {
  70. audio->replay->read_index = 0;
  71. xQueueReceiveFromISR(audio->replay->queue, &qdata, 0);
  72. for (int i = 0; i < AUDIO_REPLAY_MP_BLOCK_COUNT; i++) {
  73. if (qdata.data == audio->replay->mempool + AUDIO_REPLAY_MP_BLOCK_SIZE * i) {
  74. audio->replay->mpstatus[i] = 0;
  75. break;
  76. }
  77. }
  78. }
  79. }
  80. }
  81. if (audio->ops->transmit != NULL)
  82. {
  83. if (audio->ops->transmit(audio, &buf_info->buffer[position], NULL, dst_size) != dst_size)
  84. result = -1;
  85. }
  86. return result;
  87. }
  88. static int audio_flush_replay_frame(struct audio_device *audio)
  89. {
  90. int result = 0;
  91. if (audio->replay->write_index)
  92. {
  93. struct audio_queue_data qdata = {audio->replay->write_data, audio->replay->write_index};
  94. result = xQueueSend(audio->replay->queue, &qdata, portMAX_DELAY);
  95. audio->replay->write_index = 0;
  96. }
  97. return result;
  98. }
  99. static int audio_replay_start(struct audio_device *audio)
  100. {
  101. int result = 0;
  102. if (audio->replay->activated != true)
  103. {
  104. /* start playback hardware device */
  105. if (audio->ops->start)
  106. result = audio->ops->start(audio, AUDIO_STREAM_REPLAY);
  107. audio->replay->activated = true;
  108. TRACE_DEBUG("start audio replay device");
  109. }
  110. return result;
  111. }
  112. static int audio_replay_stop(struct audio_device *audio)
  113. {
  114. int result = 0;
  115. if (audio->replay->activated == true)
  116. {
  117. /* flush replay remian frames */
  118. audio_flush_replay_frame(audio);
  119. /* notify irq(or thread) to stop the data transmission */
  120. audio->replay->event |= REPLAY_EVT_STOP;
  121. /* waiting for the remaining data transfer to complete */
  122. xQueueReset(audio->replay->cmp);
  123. xQueueReceive(audio->replay->cmp, NULL, pdMS_TO_TICKS(1000));
  124. audio->replay->event &= ~REPLAY_EVT_STOP;
  125. /* stop playback hardware device */
  126. if (audio->ops->stop)
  127. result = audio->ops->stop(audio, AUDIO_STREAM_REPLAY);
  128. audio->replay->activated = false;
  129. TRACE_DEBUG("stop audio replay device");
  130. }
  131. return result;
  132. }
  133. static int audio_record_start(struct audio_device *audio)
  134. {
  135. int result = 0;
  136. if (audio->record->activated != true)
  137. {
  138. /* open audio record pipe */
  139. //device_open(RT_DEVICE(&audio->record->pipe), RT_DEVICE_OFLAG_RDONLY);
  140. /* start record hardware device */
  141. if (audio->ops->start)
  142. result = audio->ops->start(audio, AUDIO_STREAM_RECORD);
  143. audio->record->activated = true;
  144. TRACE_DEBUG("start audio record device");
  145. }
  146. return result;
  147. }
  148. static int audio_record_stop(struct audio_device *audio)
  149. {
  150. int result = 0;
  151. if (audio->record->activated == true)
  152. {
  153. /* stop record hardware device */
  154. if (audio->ops->stop)
  155. result = audio->ops->stop(audio, AUDIO_STREAM_RECORD);
  156. /* close audio record pipe */
  157. //device_close(RT_DEVICE(&audio->record->pipe));
  158. audio->record->activated = false;
  159. TRACE_DEBUG("stop audio record device");
  160. }
  161. return result;
  162. }
  163. static int audio_dev_init(struct audio_device *audio)
  164. {
  165. int result = 0;
  166. configASSERT(audio != NULL);
  167. /* initialize replay & record */
  168. audio->replay = NULL;
  169. audio->record = NULL;
  170. /* initialize replay */
  171. if (audio->flag == AUDIO_FLAG_REPLAY)
  172. {
  173. struct audio_replay *replay = (struct audio_replay *) pvPortMalloc(sizeof(struct audio_replay));
  174. if (replay == NULL)
  175. return -ENOMEM;
  176. memset(replay, 0, sizeof(struct audio_replay));
  177. /* alloc mempool */
  178. replay->mempool = pvPortMalloc(AUDIO_REPLAY_MP_BLOCK_SIZE * AUDIO_REPLAY_MP_BLOCK_COUNT);
  179. if (!replay->mempool)
  180. return -ENOMEM;
  181. /* init queue for audio replay */
  182. replay->queue = xQueueCreate(CFG_AUDIO_REPLAY_QUEUE_COUNT, sizeof(struct audio_queue_data));
  183. /* init mutex lock for audio replay */
  184. replay->lock = xSemaphoreCreateMutex();
  185. replay->cmp = xQueueCreate(1, 0);
  186. replay->activated = false;
  187. audio->replay = replay;
  188. }
  189. /* initialize record */
  190. else if (audio->flag == AUDIO_FLAG_RECORD)
  191. {
  192. struct audio_record *record = (struct audio_record *) pvPortMalloc(sizeof(struct audio_record));
  193. uint8_t *buffer;
  194. if (record == NULL)
  195. return -ENOMEM;
  196. memset(record, 0, sizeof(struct audio_record));
  197. /* init pipe for record*/
  198. buffer = pvPortMalloc(AUDIO_RECORD_PIPE_SIZE);
  199. if (buffer == NULL)
  200. {
  201. vPortFree(record);
  202. TRACE_ERROR("malloc memory for for record pipe failed");
  203. return -ENOMEM;
  204. }
  205. /* audio_pipe_init(&record->pipe, "record",
  206. (int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD),
  207. buffer,
  208. RT_AUDIO_RECORD_PIPE_SIZE); */
  209. record->activated = false;
  210. audio->record = record;
  211. }
  212. /* initialize hardware configuration */
  213. if (audio->ops->init)
  214. audio->ops->init(audio);
  215. /* get replay buffer information */
  216. if (audio->ops->buffer_info)
  217. audio->ops->buffer_info(audio, &audio->replay->buf_info);
  218. return result;
  219. }
  220. struct audio_device *audio_dev_open(uint32_t oflag)
  221. {
  222. struct audio_device *audio = NULL;
  223. /* initialize the Rx/Tx structure according to open flag */
  224. if (oflag == AUDIO_FLAG_REPLAY)
  225. {
  226. audio = audio_dev[AUDIO_FLAG_REPLAY];
  227. if (audio && audio->replay->activated != true)
  228. {
  229. TRACE_DEBUG("open audio replay device, oflag = %x\n", oflag);
  230. audio->replay->write_index = 0;
  231. audio->replay->read_index = 0;
  232. audio->replay->pos = 0;
  233. audio->replay->event = REPLAY_EVT_NONE;
  234. for (int i = 0; i < AUDIO_REPLAY_MP_BLOCK_COUNT; i++)
  235. audio->replay->mpstatus[i] = 0;
  236. }
  237. }
  238. else if (oflag == AUDIO_FLAG_RECORD)
  239. {
  240. audio = audio_dev[AUDIO_FLAG_RECORD];
  241. /* open record pipe */
  242. if (audio && audio->record->activated != true)
  243. {
  244. TRACE_DEBUG("open audio record device ,oflag = %x\n", oflag);
  245. audio_record_start(audio);
  246. audio->record->activated = true;
  247. }
  248. }
  249. return audio;
  250. }
  251. int audio_dev_close(struct audio_device *audio)
  252. {
  253. configASSERT(audio != NULL);
  254. if (audio->flag == AUDIO_FLAG_REPLAY)
  255. {
  256. /* stop replay stream */
  257. audio_replay_stop(audio);
  258. }
  259. else if (audio->flag == AUDIO_FLAG_RECORD)
  260. {
  261. /* stop record stream */
  262. audio_record_stop(audio);
  263. }
  264. return 0;
  265. }
  266. size_t audio_dev_read(struct audio_device *audio, void *buffer, size_t size)
  267. {
  268. configASSERT(audio != NULL);
  269. if (!(audio->flag == AUDIO_FLAG_RECORD) || (audio->record == NULL))
  270. return 0;
  271. return 0;//device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size);
  272. }
  273. size_t audio_dev_write(struct audio_device *audio, const void *buffer, size_t size)
  274. {
  275. uint8_t *ptr;
  276. uint16_t block_size, remain_bytes, index = 0;
  277. configASSERT(audio != NULL);
  278. if (!(audio->flag == AUDIO_FLAG_REPLAY) || (audio->replay == NULL))
  279. return 0;
  280. /* push a new frame to replay data queue */
  281. ptr = (uint8_t *)buffer;
  282. block_size = AUDIO_REPLAY_MP_BLOCK_SIZE;
  283. xSemaphoreTake(audio->replay->lock, portMAX_DELAY);
  284. while (index < size)
  285. {
  286. /* request buffer from replay memory pool */
  287. if (audio->replay->write_index % block_size == 0)
  288. {
  289. uint8_t *mpbuf = NULL;
  290. uint32_t st = xTaskGetTickCount();
  291. while(1) {
  292. int i;
  293. portENTER_CRITICAL();
  294. for (i = 0; i < AUDIO_REPLAY_MP_BLOCK_COUNT; i++) {
  295. if (!audio->replay->mpstatus[i]) {
  296. mpbuf = audio->replay->mempool + AUDIO_REPLAY_MP_BLOCK_SIZE * i;
  297. audio->replay->mpstatus[i] = 1;
  298. break;
  299. }
  300. }
  301. portEXIT_CRITICAL();
  302. if (mpbuf)
  303. break;
  304. if (xTaskGetTickCount() - st > pdMS_TO_TICKS(1000)) {
  305. printf("wait mempool free timeout.\n");
  306. mpbuf = audio->replay->mempool;
  307. for (i = 1; i < AUDIO_REPLAY_MP_BLOCK_COUNT; i++)
  308. audio->replay->mpstatus[i] = 0;
  309. break;
  310. }
  311. vTaskDelay(1);
  312. }
  313. audio->replay->write_data = mpbuf;
  314. memset(audio->replay->write_data, 0, block_size);
  315. }
  316. /* copy data to replay memory pool */
  317. remain_bytes = configMIN((block_size - audio->replay->write_index), (size - index));
  318. memcpy(&audio->replay->write_data[audio->replay->write_index], &ptr[index], remain_bytes);
  319. index += remain_bytes;
  320. audio->replay->write_index += remain_bytes;
  321. audio->replay->write_index %= block_size;
  322. if (audio->replay->write_index == 0)
  323. {
  324. struct audio_queue_data qdata = {audio->replay->write_data, block_size};
  325. xQueueSend(audio->replay->queue, &qdata, portMAX_DELAY);
  326. }
  327. }
  328. xSemaphoreGive(audio->replay->lock);
  329. /* check replay state */
  330. if (audio->replay->activated != true)
  331. {
  332. audio_replay_start(audio);
  333. audio->replay->activated = true;
  334. }
  335. return index;
  336. }
  337. int audio_dev_configure(struct audio_device *audio, struct audio_caps *caps)
  338. {
  339. int result = 0;
  340. if (audio->ops->configure != NULL)
  341. {
  342. result = audio->ops->configure(audio, caps);
  343. }
  344. return result;
  345. }
  346. int audio_register(struct audio_device *audio, uint32_t flag, void *data)
  347. {
  348. int result = 0;
  349. configASSERT(audio != NULL);
  350. audio->rx_indicate = NULL;
  351. audio->tx_complete = NULL;
  352. audio->flag = flag;
  353. audio->user_data = data;
  354. /* initialize audio device */
  355. result = audio_dev_init(audio);
  356. if (flag == AUDIO_FLAG_REPLAY)
  357. audio_dev[AUDIO_FLAG_REPLAY] = audio;
  358. else if (flag == AUDIO_FLAG_RECORD)
  359. audio_dev[AUDIO_FLAG_RECORD] = audio;
  360. return result;
  361. }
  362. int audio_samplerate_to_speed(uint32_t bitValue)
  363. {
  364. int speed = 0;
  365. switch (bitValue)
  366. {
  367. case AUDIO_SAMP_RATE_8K:
  368. speed = 8000;
  369. break;
  370. case AUDIO_SAMP_RATE_11K:
  371. speed = 11052;
  372. break;
  373. case AUDIO_SAMP_RATE_16K:
  374. speed = 16000;
  375. break;
  376. case AUDIO_SAMP_RATE_22K:
  377. speed = 22050;
  378. break;
  379. case AUDIO_SAMP_RATE_32K:
  380. speed = 32000;
  381. break;
  382. case AUDIO_SAMP_RATE_44K:
  383. speed = 44100;
  384. break;
  385. case AUDIO_SAMP_RATE_48K:
  386. speed = 48000;
  387. break;
  388. case AUDIO_SAMP_RATE_96K:
  389. speed = 96000;
  390. break;
  391. case AUDIO_SAMP_RATE_128K:
  392. speed = 128000;
  393. break;
  394. case AUDIO_SAMP_RATE_160K:
  395. speed = 160000;
  396. break;
  397. case AUDIO_SAMP_RATE_172K:
  398. speed = 176400;
  399. break;
  400. case AUDIO_SAMP_RATE_192K:
  401. speed = 192000;
  402. break;
  403. default:
  404. break;
  405. }
  406. return speed;
  407. }
  408. void audio_tx_complete(struct audio_device *audio)
  409. {
  410. /* try to send next frame */
  411. audio_send_replay_frame(audio);
  412. }
  413. void audio_rx_done(struct audio_device *audio, uint8_t *pbuf, size_t len)
  414. {
  415. /* save data to record pipe */
  416. //device_write(RT_DEVICE(&audio->record->pipe), 0, pbuf, len);
  417. /* invoke callback */
  418. /* if (audio->parent.rx_indicate != NULL)
  419. audio->parent.rx_indicate(&audio->parent, len); */
  420. }