* @brief Write data into replay data queue and replay it * * @param[in] dev pointer to device * * @param[in] pos useless param * * @param[in] buffer a data buffer to be written into data queue * * @param[in] size buffer size * * @return the actually read size on successfully, otherwise 0 will be returned. * * @note This function will take mutex. */
| 489 | * @note This function will take mutex. |
| 490 | */ |
| 491 | static rt_ssize_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) |
| 492 | { |
| 493 | |
| 494 | struct rt_audio_device *audio; |
| 495 | rt_uint8_t *ptr; |
| 496 | rt_uint16_t block_size, remain_bytes, index = 0; |
| 497 | |
| 498 | RT_ASSERT(dev != RT_NULL); |
| 499 | audio = (struct rt_audio_device *) dev; |
| 500 | |
| 501 | if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL)) |
| 502 | return 0; |
| 503 | |
| 504 | /* push a new frame to replay data queue */ |
| 505 | ptr = (rt_uint8_t *)buffer; |
| 506 | block_size = RT_AUDIO_REPLAY_MP_BLOCK_SIZE; |
| 507 | |
| 508 | rt_mutex_take(&audio->replay->lock, RT_WAITING_FOREVER); |
| 509 | while (index < size) |
| 510 | { |
| 511 | /* request buffer from replay memory pool */ |
| 512 | if (audio->replay->write_index % block_size == 0) |
| 513 | { |
| 514 | audio->replay->write_data = rt_mp_alloc(audio->replay->mp, RT_WAITING_FOREVER); |
| 515 | rt_memset(audio->replay->write_data, 0, block_size); |
| 516 | } |
| 517 | |
| 518 | /* copy data to replay memory pool */ |
| 519 | remain_bytes = MIN((block_size - audio->replay->write_index), (size - index)); |
| 520 | rt_memcpy(&audio->replay->write_data[audio->replay->write_index], &ptr[index], remain_bytes); |
| 521 | |
| 522 | index += remain_bytes; |
| 523 | audio->replay->write_index += remain_bytes; |
| 524 | audio->replay->write_index %= block_size; |
| 525 | |
| 526 | if (audio->replay->write_index == 0) |
| 527 | { |
| 528 | rt_data_queue_push(&audio->replay->queue, |
| 529 | audio->replay->write_data, |
| 530 | block_size, |
| 531 | RT_WAITING_FOREVER); |
| 532 | } |
| 533 | } |
| 534 | rt_mutex_release(&audio->replay->lock); |
| 535 | |
| 536 | /* check replay state */ |
| 537 | if (audio->replay->activated != RT_TRUE) |
| 538 | { |
| 539 | _aduio_replay_start(audio); |
| 540 | audio->replay->activated = RT_TRUE; |
| 541 | } |
| 542 | |
| 543 | return index; |
| 544 | } |
| 545 | |
| 546 | /** |
| 547 | * @brief Control audio device |
nothing calls this directly
no test coverage detected