diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c index 3476d06412..0b2f9a0cdd 100644 --- a/components/drivers/audio/audio.c +++ b/components/drivers/audio/audio.c @@ -1,8 +1,25 @@ /* - * audio.c + * File : audio.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * Created on: 2016年10月19日 - * Author: Urey + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-05-09 Urey first version */ #include @@ -19,374 +36,61 @@ #define AUDIO_DBG(...) #endif - -rt_err_t _audio_queue_init(struct rt_audio_queue *queue, rt_uint16_t size, rt_uint16_t lwm) -{ - RT_ASSERT(queue != RT_NULL); - - queue->count = 0; - queue->size = size; - queue->lwm = lwm; - queue->waiting_lwm = RT_FALSE; - - queue->get_index = 0; - queue->put_index = 0; - - rt_list_init(&(queue->suspended_push_list)); - rt_list_init(&(queue->suspended_pop_list)); - - queue->queue = (struct rt_audio_frame *)rt_malloc(sizeof(struct rt_audio_frame) * size); - if (queue->queue == RT_NULL) - { - return -RT_ENOMEM; - } - - return RT_EOK; -} - -rt_err_t _audio_queue_push(struct rt_audio_queue *queue, struct rt_audio_frame *frame, rt_int32_t timeout) -{ - rt_ubase_t level; - rt_thread_t thread; - rt_err_t result; - - RT_ASSERT(queue != RT_NULL); - - result = RT_EOK; - thread = rt_thread_self(); - - AUDIO_DBG("%s count = %d\n",__func__,queue->count); - - level = rt_hw_interrupt_disable(); - while(queue->count == queue->size) - {// audio queue is full - queue->waiting_lwm = RT_TRUE; - - /* queue is full */ - if (timeout == 0) - { - result = -RT_ETIMEOUT; - goto __exit; - } - - /* current context checking */ - RT_DEBUG_NOT_IN_INTERRUPT; - - /* reset thread error number */ - thread->error = RT_EOK; - - /* suspend thread on the push list */ - rt_thread_suspend(thread); - rt_list_insert_before(&(queue->suspended_push_list), &(thread->tlist)); - /* start timer */ - if (timeout > 0) - { - /* reset the timeout of thread timer and start it */ - rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); - rt_timer_start(&(thread->thread_timer)); - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - /* do schedule */ - rt_schedule(); - - /* thread is waked up */ - result = thread->error; - level = rt_hw_interrupt_disable(); - if (result != RT_EOK) goto __exit; - } - - queue->queue[queue->put_index].data_ptr = frame->data_ptr; - queue->queue[queue->put_index].data_size = frame->data_size; - queue->queue[queue->put_index].data_ofs = frame->data_ofs; - queue->put_index = (queue->put_index + 1) % queue->size; - queue->count ++; - - if (!rt_list_isempty(&(queue->suspended_pop_list))) - { - /* there is at least one thread in suspended list */ - - /* get thread entry */ - thread = rt_list_entry(queue->suspended_pop_list.next, - struct rt_thread, - tlist); - - /* resume it */ - rt_thread_resume(thread); - rt_hw_interrupt_enable(level); - - /* perform a schedule */ - rt_schedule(); - - return result; - } -__exit: - rt_hw_interrupt_enable(level); - - return result; -} - -rt_err_t _audio_queue_pop(struct rt_audio_queue *queue, struct rt_audio_frame *frame, rt_int32_t timeout) -{ - rt_ubase_t level; - rt_thread_t thread; - rt_err_t result; - - RT_ASSERT(queue != RT_NULL); - RT_ASSERT(frame != RT_NULL); - - result = RT_EOK; - thread = rt_thread_self(); - - AUDIO_DBG("%s count = %d\n",__func__,queue->count); - - level = rt_hw_interrupt_disable(); - while (queue->count == 0) - { - /* queue is empty */ - if (timeout == 0) - { - result = -RT_ETIMEOUT; - goto __exit; - } - - /* current context checking */ - RT_DEBUG_NOT_IN_INTERRUPT; - - /* reset thread error number */ - thread->error = RT_EOK; - - /* suspend thread on the pop list */ - rt_thread_suspend(thread); - rt_list_insert_before(&(queue->suspended_pop_list), &(thread->tlist)); - /* start timer */ - if (timeout > 0) - { - /* reset the timeout of thread timer and start it */ - rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); - rt_timer_start(&(thread->thread_timer)); - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - /* do schedule */ - rt_schedule(); - - /* thread is waked up */ - result = thread->error; - level = rt_hw_interrupt_disable(); - if (result != RT_EOK) - goto __exit; - } - - frame->data_ptr = queue->queue[queue->get_index].data_ptr; - frame->data_size = queue->queue[queue->get_index].data_size; - frame->data_ofs = queue->queue[queue->get_index].data_ofs; - - queue->get_index = (queue->get_index + 1) % queue->size; - queue->count --; - - if ((queue->waiting_lwm == RT_TRUE) && - (queue->put_index - queue->get_index) <= queue->lwm) - { - queue->waiting_lwm = RT_FALSE; - - /* - * there is at least one thread in suspended list - * and less than low water mark - */ - if (!rt_list_isempty(&(queue->suspended_push_list))) - { - /* get thread entry */ - thread = rt_list_entry(queue->suspended_push_list.next, - struct rt_thread, - tlist); - - /* resume it */ - rt_thread_resume(thread); - rt_hw_interrupt_enable(level); - - /* perform a schedule */ - rt_schedule(); - } - - return result; - } -__exit: - rt_hw_interrupt_enable(level); - return result; -} - -rt_err_t _audio_queue_peak(struct rt_audio_queue *queue, struct rt_audio_frame *frame) -{ - rt_ubase_t level; - - RT_ASSERT(queue != RT_NULL); - - AUDIO_DBG("%s count = %d\n",__func__,queue->count); - - level = rt_hw_interrupt_disable(); - if (queue->count == 0) - { - rt_hw_interrupt_enable(level); - - return -RT_EEMPTY; - } - - frame->data_ptr = queue->queue[queue->get_index].data_ptr; - frame->data_size = queue->queue[queue->get_index].data_size; - frame->data_ofs = queue->queue[queue->get_index].data_ofs; - - rt_hw_interrupt_enable(level); - - return RT_EOK; -} - -rt_err_t _audio_queue_unpeak(struct rt_audio_queue *queue, struct rt_audio_frame *frame) -{ - rt_ubase_t level; - - RT_ASSERT(queue != RT_NULL); - - level = rt_hw_interrupt_disable(); - - if (queue->count == 0) - { - rt_hw_interrupt_enable(level); - - return -RT_EEMPTY; - } - - queue->queue[queue->get_index].data_ptr = frame->data_ptr; - queue->queue[queue->get_index].data_size = frame->data_size; - queue->queue[queue->get_index].data_ofs = frame->data_ofs; - - rt_hw_interrupt_enable(level); - - return RT_EOK; -} - -rt_err_t _audio_queue_reset(struct rt_audio_queue *queue) -{ - struct rt_thread *thread; - register rt_ubase_t temp; - - rt_enter_critical(); - - /* wakeup all suspend threads */ - /* resume on pop list */ - while (!rt_list_isempty(&(queue->suspended_pop_list))) - { - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); - - /* get next suspend thread */ - thread = rt_list_entry(queue->suspended_pop_list.next, - struct rt_thread, - tlist); - /* set error code to RT_ERROR */ - thread->error = -RT_ERROR; - - /* - * resume thread - * In rt_thread_resume function, it will remove current thread from - * suspend list - */ - rt_thread_resume(thread); - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - } - - /* resume on push list */ - while (!rt_list_isempty(&(queue->suspended_push_list))) - { - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); - - /* get next suspend thread */ - thread = rt_list_entry(queue->suspended_push_list.next, - struct rt_thread, - tlist); - /* set error code to RT_ERROR */ - thread->error = -RT_ERROR; - - /* - * resume thread - * In rt_thread_resume function, it will remove current thread from - * suspend list - */ - rt_thread_resume(thread); - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - } - rt_exit_critical(); - - rt_schedule(); -} - - static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio) { - rt_err_t result = RT_EOK; - rt_base_t level; - struct rt_audio_frame frame; + rt_err_t result = RT_EOK; + rt_base_t level; + struct rt_audio_frame frame; RT_ASSERT(audio != RT_NULL); - //check repaly queue is empty - if(_audio_queue_peak(&audio->replay->queue,&frame) != RT_EOK) - { - AUDIO_DBG("TX queue is empty\n"); - result = -RT_EEMPTY; + //check repaly queue is empty + if (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) != RT_EOK) + { + AUDIO_DBG("TX queue is empty\n"); + result = -RT_EEMPTY; - level = rt_hw_interrupt_disable(); - audio->replay->activated = RT_FALSE; - rt_hw_interrupt_enable(level); + level = rt_hw_interrupt_disable(); + audio->replay->activated = RT_FALSE; + rt_hw_interrupt_enable(level); - goto _exit; - } + goto _exit; + } - if(audio->ops->transmit != RT_NULL) - { - AUDIO_DBG("audio transmit...\n"); - if(audio->ops->transmit(audio,frame.data_ptr,RT_NULL, frame.data_size) != frame.data_size) - { - result = -RT_EBUSY; + if (audio->ops->transmit != RT_NULL) + { + AUDIO_DBG("audio transmit...\n"); + if (audio->ops->transmit(audio, frame.data_ptr, RT_NULL, frame.data_size) != frame.data_size) + { + result = -RT_EBUSY; - goto _exit; - } - } + goto _exit; + } + } - //pop the head frame... - _audio_queue_pop(&audio->replay->queue,&frame,RT_WAITING_NO); + //pop the head frame... + rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER); -_exit: - return result; + _exit: return result; } static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio) { - struct rt_audio_frame frame; + struct rt_audio_frame frame; - if(audio->replay == RT_NULL) - return -RT_EIO; + if (audio->replay == RT_NULL) + return -RT_EIO; + while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK) + { + //pop the head frame... + rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER); - while(_audio_queue_peak(&audio->replay->queue,&frame) == RT_EOK) - { - //pop the head frame... - _audio_queue_pop(&audio->replay->queue,&frame,RT_WAITING_NO); + /* notify transmitted complete. */ + if (audio->parent.tx_complete != RT_NULL) + audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr); + } - /* notify transmitted complete. */ - if(audio->parent.tx_complete != RT_NULL) - audio->parent.tx_complete(&audio->parent,(void *)frame.data_ptr); - } - - return RT_EOK; + return RT_EOK; } static rt_err_t _audio_dev_init(struct rt_device *dev) @@ -395,7 +99,7 @@ static rt_err_t _audio_dev_init(struct rt_device *dev) struct rt_audio_device *audio; RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *)dev; + audio = (struct rt_audio_device *) dev; /* initialize replay & record */ audio->replay = RT_NULL; @@ -410,12 +114,12 @@ static rt_err_t _audio_dev_init(struct rt_device *dev) static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag) { - rt_err_t result = RT_EOK; - rt_base_t level; - struct rt_audio_device *audio; + rt_err_t result = RT_EOK; + rt_base_t level; + struct rt_audio_device *audio; RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *)dev; + audio = (struct rt_audio_device *) dev; /* check device flag with the open flag */ if ((oflag & RT_DEVICE_OFLAG_RDONLY) && !(dev->flag & RT_DEVICE_FLAG_RDONLY)) @@ -429,64 +133,65 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag) /* initialize the Rx/Tx structure according to open flag */ if (oflag & RT_DEVICE_OFLAG_WRONLY) { - AUDIO_DBG("open audio device ,oflag = %x\n",oflag); - if(audio->replay == RT_NULL) - { - struct rt_audio_replay *replay = (struct rt_audio_replay *)rt_malloc(sizeof(struct rt_audio_replay)); + AUDIO_DBG("open audio device ,oflag = %x\n",oflag); + if (audio->replay == RT_NULL) + { + struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay)); - if(replay == RT_NULL) - { - AUDIO_DBG("request memory for replay error\n"); - return -RT_ENOMEM; - } + if (replay == RT_NULL) + { + AUDIO_DBG("request memory for replay error\n"); + return -RT_ENOMEM; + } - //init queue for audio replay - _audio_queue_init(&replay->queue,CFG_AUDIO_REPLAY_QUEUE_COUNT,CFG_AUDIO_REPLAY_QUEUE_COUNT / 2); + //init queue for audio replay + rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, CFG_AUDIO_REPLAY_QUEUE_COUNT / 2, RT_NULL); - replay->activated = RT_FALSE; - audio->replay = replay; - } + replay->activated = RT_FALSE; + audio->replay = replay; + } dev->open_flag |= RT_DEVICE_OFLAG_WRONLY; } - if(oflag & RT_DEVICE_OFLAG_RDONLY) + if (oflag & RT_DEVICE_OFLAG_RDONLY) { - if(audio->record == RT_NULL) - { - struct rt_audio_record *record = (struct rt_audio_record *)rt_malloc(sizeof(struct rt_audio_record)); + if (audio->record == RT_NULL) + { + struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record)); - if(record == RT_NULL) - { - AUDIO_DBG("request memory for record error\n"); - return -RT_ENOMEM; - } + if (record == RT_NULL) + { + AUDIO_DBG("request memory for record error\n"); + return -RT_ENOMEM; + } - //init pipe for record - { - rt_size_t size = CFG_AUDIO_RECORD_PIPE_SIZE; - rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE); + //init pipe for record + { + rt_size_t size = CFG_AUDIO_RECORD_PIPE_SIZE; + rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE); - if(buf == RT_NULL) - { - rt_free(record); - AUDIO_DBG("request pipe memory error\n"); + if (buf == RT_NULL) + { + rt_free(record); + AUDIO_DBG("request pipe memory error\n"); - return -RT_ENOMEM; - } + return -RT_ENOMEM; + } - rt_pipe_init(&record->pipe,"recpipe",RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD,buf,CFG_AUDIO_RECORD_PIPE_SIZE); - } + rt_pipe_init(&record->pipe, "recpipe", RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD, buf, + CFG_AUDIO_RECORD_PIPE_SIZE); + } - record->activated = RT_FALSE; - audio->record = record; - } + record->activated = RT_FALSE; + audio->record = record; + } - //open record pipe - if(audio->record != RT_NULL) - { - rt_device_open(RT_DEVICE(&audio->record->pipe),RT_DEVICE_OFLAG_RDONLY); - } + //open record pipe + if (audio->record != RT_NULL) + { + rt_device_open(RT_DEVICE(&audio->record->pipe), RT_DEVICE_OFLAG_RDONLY); + } dev->open_flag |= RT_DEVICE_OFLAG_RDONLY; } @@ -496,96 +201,93 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag) static rt_err_t _audio_dev_close(struct rt_device *dev) { - struct rt_audio_device *audio; + struct rt_audio_device *audio; RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *)dev; + audio = (struct rt_audio_device *) dev; - //shutdown the lower device - if(audio->ops->shutdown != RT_NULL) - audio->ops->shutdown(audio); + //shutdown the lower device + if (audio->ops->shutdown != RT_NULL) + audio->ops->shutdown(audio); - if(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) + if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY) { - struct rt_audio_frame frame; - //stop replay stream - audio->ops->stop(audio,AUDIO_STREAM_REPLAY); + struct rt_audio_frame frame; + //stop replay stream + audio->ops->stop(audio, AUDIO_STREAM_REPLAY); - //flush all frame - while(_audio_queue_peak(&audio->replay->queue,&frame) == RT_EOK) - { - _audio_queue_pop(&audio->replay->queue,&frame,RT_WAITING_NO); + //flush all frame + while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK) + { + //pop the head frame... + rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER); - //indicate this frame complete(maybe upper device need free data) - if(dev->tx_complete != RT_NULL) - dev->tx_complete(dev,(void *)frame.data_ptr); - } + /* notify transmitted complete. */ + if (audio->parent.tx_complete != RT_NULL) + audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr); + } - dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY; + dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY; } - if(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) + if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY) { - //stop record stream - audio->ops->stop(audio,AUDIO_STREAM_RECORD); + //stop record stream + audio->ops->stop(audio, AUDIO_STREAM_RECORD); - //close record pipe - if(audio->record != RT_NULL) - rt_device_close(RT_DEVICE(&audio->record->pipe)); + //close record pipe + if (audio->record != RT_NULL) + rt_device_close(RT_DEVICE(&audio->record->pipe)); - dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY; + dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY; } - return RT_EOK; + return RT_EOK; } static rt_size_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size) { - struct rt_audio_device *audio; + struct rt_audio_device *audio; RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *)dev; - if(!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL)) - return 0; + audio = (struct rt_audio_device *) dev; + if (!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL)) + return 0; return rt_device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size); } static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) { - rt_err_t result = RT_EOK; - rt_base_t level; - struct rt_audio_device *audio; + rt_err_t result = RT_EOK; + rt_base_t level; + struct rt_audio_device *audio; RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *)dev; + audio = (struct rt_audio_device *) dev; - if(!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL)) - return 0; + if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL)) + return 0; AUDIO_DBG("audio write : pos = %d,buffer = %x,size = %d\n",pos,(rt_uint32_t)buffer,size); //push a new frame to tx queue { - struct rt_audio_frame frame; - frame.data_ptr = buffer; - frame.data_size = size; - frame.data_ofs = 0; - - result = _audio_queue_push(&audio->replay->queue,&frame,RT_WAITING_FOREVER); - if(result != RT_EOK) + result = rt_data_queue_push(&audio->replay->queue, buffer, size, + RT_WAITING_FOREVER); + if (result != RT_EOK) { - AUDIO_DBG("TX frame queue push error\n"); - rt_set_errno(-RT_EFULL); + AUDIO_DBG("TX frame queue push error\n"); + rt_set_errno(-RT_EFULL); return 0; } } //check tx state... level = rt_hw_interrupt_disable(); - if(audio->replay->activated != RT_TRUE) + if (audio->replay->activated != RT_TRUE) { - audio->replay->activated = RT_TRUE; - rt_hw_interrupt_enable(level); + audio->replay->activated = RT_TRUE; + rt_hw_interrupt_enable(level); - _audio_send_replay_frame(audio); + _audio_send_replay_frame(audio); } return size; @@ -593,251 +295,243 @@ static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const voi static rt_err_t _audio_dev_control(struct rt_device *dev, rt_uint8_t cmd, void *args) { - rt_err_t result = RT_EOK; - struct rt_audio_device *audio; + rt_err_t result = RT_EOK; + struct rt_audio_device *audio; RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *)dev; + audio = (struct rt_audio_device *) dev; //dev stat... - switch (cmd) - { - case AUDIO_CTL_GETCAPS: - { - struct rt_audio_caps *caps = (struct rt_audio_caps *) args; + switch (cmd) + { + case AUDIO_CTL_GETCAPS: + { + struct rt_audio_caps *caps = (struct rt_audio_caps *) args; - AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type); - if (audio->ops->getcaps != RT_NULL) - { - result = audio->ops->getcaps(audio, caps); - } - } - break; - case AUDIO_CTL_CONFIGURE: - { - struct rt_audio_caps *caps = (struct rt_audio_caps *) args; + AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type); + if (audio->ops->getcaps != RT_NULL) + { + result = audio->ops->getcaps(audio, caps); + } + } + break; + case AUDIO_CTL_CONFIGURE: + { + struct rt_audio_caps *caps = (struct rt_audio_caps *) args; - AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type); - if (audio->ops->configure != RT_NULL) - { - result = audio->ops->configure(audio, caps); - } - } + AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type); + if (audio->ops->configure != RT_NULL) + { + result = audio->ops->configure(audio, caps); + } + } - break; - case AUDIO_CTL_SHUTDOWN: - { - AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n"); + break; + case AUDIO_CTL_SHUTDOWN: + { + AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n"); - if (audio->ops->shutdown != RT_NULL) - result = audio->ops->shutdown(audio); + if (audio->ops->shutdown != RT_NULL) + result = audio->ops->shutdown(audio); - //flush replay frame... - _audio_flush_replay_frame(audio); - } - break; + //flush replay frame... + _audio_flush_replay_frame(audio); + } + break; - case AUDIO_CTL_START: - { - int stream = *(int *) args; + case AUDIO_CTL_START: + { + int stream = *(int *) args; - AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream); - if (audio->ops->start != RT_NULL) - result = audio->ops->start(audio, stream); - } - break; - case AUDIO_CTL_STOP: - { - int stream = *(int *) args; + AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream); + if (audio->ops->start != RT_NULL) + result = audio->ops->start(audio, stream); + } + break; + case AUDIO_CTL_STOP: + { + int stream = *(int *) args; - AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream); - if (audio->ops->start != RT_NULL) - result = audio->ops->stop(audio, stream); + AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream); + if (audio->ops->start != RT_NULL) + result = audio->ops->stop(audio, stream); - if(stream == AUDIO_STREAM_REPLAY) - { - _audio_flush_replay_frame(audio); - } - } - break; - case AUDIO_CTL_PAUSE: - { - int stream = *(int *) args; + if (stream == AUDIO_STREAM_REPLAY) + { + _audio_flush_replay_frame(audio); + } + } + break; + case AUDIO_CTL_PAUSE: + { + int stream = *(int *) args; - AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream); - if (audio->ops->start != RT_NULL) - result = audio->ops->suspend(audio, stream); - } - break; - case AUDIO_CTL_RESUME: - { - int stream = *(int *) args; + AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream); + if (audio->ops->start != RT_NULL) + result = audio->ops->suspend(audio, stream); + } + break; + case AUDIO_CTL_RESUME: + { + int stream = *(int *) args; - AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream); - if (audio->ops->start != RT_NULL) - result = audio->ops->resume(audio, stream); + AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream); + if (audio->ops->start != RT_NULL) + result = audio->ops->resume(audio, stream); - //resume tx frame... - if(stream == AUDIO_STREAM_REPLAY) - _audio_send_replay_frame(audio); - } - break; -#ifdef AUDIO_DEVICE_USE_PRIVATE_BUFFER - case AUDIO_CTL_ALLOCBUFFER: - { - struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *)args; + //resume tx frame... + if (stream == AUDIO_STREAM_REPLAY) + _audio_send_replay_frame(audio); + } + break; + case AUDIO_CTL_ALLOCBUFFER: + { + struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *) args; - if((audio->ops->buffer_alloc != RT_NULL) && (desc != RT_NULL)) - { - result = audio->ops->buffer_alloc(audio,&desc->data_ptr,&desc->data_size); - break; - } + if (desc) + { + desc->data_size = AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2; + desc->data_ptr = rt_mp_alloc(&audio->mp, RT_WAITING_FOREVER); - result = -RT_EIO; - } - break; - case AUDIO_CTL_FREEBUFFER: - { - rt_uint8_t *data_ptr = (rt_uint8_t *)args; - if((audio->ops->buffer_free != RT_NULL) && (data_ptr != RT_NULL)) - { - audio->ops->buffer_free(audio,data_ptr); - break; - } - } - break; -#endif - default: - result = audio->ops->control(audio, cmd, args); - break; - } + result = RT_EOK; + } + else result = -RT_EIO; + } + break; + case AUDIO_CTL_FREEBUFFER: + { + rt_uint8_t *data_ptr = (rt_uint8_t *) args; + if (data_ptr) + rt_mp_free(data_ptr); + } + break; + default: + result = audio->ops->control(audio, cmd, args); + break; + } return result; } - rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data) { struct rt_device *device; RT_ASSERT(audio != RT_NULL); device = &(audio->parent); - device->type = RT_Device_Class_Sound; + device->type = RT_Device_Class_Sound; device->rx_indicate = RT_NULL; device->tx_complete = RT_NULL; - device->init = _audio_dev_init; - device->open = _audio_dev_open; - device->close = _audio_dev_close; - device->read = _audio_dev_read; - device->write = _audio_dev_write; - device->control = _audio_dev_control; - device->user_data = data; + device->init = _audio_dev_init; + device->open = _audio_dev_open; + device->close = _audio_dev_close; + device->read = _audio_dev_read; + device->write = _audio_dev_write; + device->control = _audio_dev_control; + device->user_data = data; + + //init memory pool for replay + { + rt_uint8_t *mempool = rt_malloc(AUDIO_DEVICE_DECODE_MP_SZ); + rt_mp_init(&audio->mp, "adu_mp", mempool, AUDIO_DEVICE_DECODE_MP_SZ, + AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2); + } /* register a character device */ return rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE); } - - -rt_size_t rt_audio_get_buffer_size(struct rt_audio_device *audio) -{ -// return (audio->config.period_count * audio->config.period_size); - return 0; -} - int rt_audio_samplerate_to_speed(rt_uint32_t bitValue) { - int speed = 0; - switch (bitValue) - { - case AUDIO_SAMP_RATE_8K: - speed = 8000; - break; - case AUDIO_SAMP_RATE_11K: - speed = 11052; - break; - case AUDIO_SAMP_RATE_16K: - speed = 16000; - break; - case AUDIO_SAMP_RATE_22K: - speed = 22050; - break; - case AUDIO_SAMP_RATE_32K: - speed = 32000; - break; - case AUDIO_SAMP_RATE_44K: - speed = 44100; - break; - case AUDIO_SAMP_RATE_48K: - speed = 48000; - break; - case AUDIO_SAMP_RATE_96K: - speed = 96000; - break; - case AUDIO_SAMP_RATE_128K: - speed = 128000; - break; - case AUDIO_SAMP_RATE_160K: - speed = 160000; - break; - case AUDIO_SAMP_RATE_172K: - speed = 176400; - break; - case AUDIO_SAMP_RATE_192K: - speed = 192000; - break; - default: + int speed = 0; + switch (bitValue) + { + case AUDIO_SAMP_RATE_8K: + speed = 8000; + break; + case AUDIO_SAMP_RATE_11K: + speed = 11052; + break; + case AUDIO_SAMP_RATE_16K: + speed = 16000; + break; + case AUDIO_SAMP_RATE_22K: + speed = 22050; + break; + case AUDIO_SAMP_RATE_32K: + speed = 32000; + break; + case AUDIO_SAMP_RATE_44K: + speed = 44100; + break; + case AUDIO_SAMP_RATE_48K: + speed = 48000; + break; + case AUDIO_SAMP_RATE_96K: + speed = 96000; + break; + case AUDIO_SAMP_RATE_128K: + speed = 128000; + break; + case AUDIO_SAMP_RATE_160K: + speed = 160000; + break; + case AUDIO_SAMP_RATE_172K: + speed = 176400; + break; + case AUDIO_SAMP_RATE_192K: + speed = 192000; + break; + default: - break; - } + break; + } - return speed; + return speed; } - - rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format) { switch (format) { - case AUDIO_FMT_PCM_U8: - case AUDIO_FMT_PCM_S8: - return 8; - case AUDIO_FMT_PCM_S16_LE: - case AUDIO_FMT_PCM_S16_BE: - case AUDIO_FMT_PCM_U16_LE: - case AUDIO_FMT_PCM_U16_BE: - return 16; - default: - return 32; + case AUDIO_FMT_PCM_U8: + case AUDIO_FMT_PCM_S8: + return 8; + case AUDIO_FMT_PCM_S16_LE: + case AUDIO_FMT_PCM_S16_BE: + case AUDIO_FMT_PCM_U16_LE: + case AUDIO_FMT_PCM_U16_BE: + return 16; + default: + return 32; }; } -void rt_audio_tx_complete(struct rt_audio_device *audio,rt_uint8_t *pbuf) +void rt_audio_tx_complete(struct rt_audio_device *audio, rt_uint8_t *pbuf) { - rt_err_t result; - AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf); + rt_err_t result; + AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf); - //try to send all frame - do - { - result = _audio_send_replay_frame(audio); - }while(result == RT_EOK); + //try to send all frame + do + { + result = _audio_send_replay_frame(audio); + } while (result == RT_EOK); - /* notify transmitted complete. */ - if(audio->parent.tx_complete != RT_NULL) - audio->parent.tx_complete(&audio->parent,(void *)pbuf); + /* notify transmitted complete. */ + if (audio->parent.tx_complete != RT_NULL) + audio->parent.tx_complete(&audio->parent, (void *) pbuf); } -void rt_audio_rx_done(struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len) +void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len) { - rt_err_t result = RT_EOK; + rt_err_t result = RT_EOK; //save data to record pipe - rt_device_write(RT_DEVICE(RT_DEVICE(&audio->record->pipe)),0,pbuf,len); + rt_device_write(RT_DEVICE(RT_DEVICE(&audio->record->pipe)), 0, pbuf, len); /* invoke callback */ - if(audio->parent.rx_indicate != RT_NULL) - audio->parent.rx_indicate(&audio->parent,len); + if (audio->parent.rx_indicate != RT_NULL) + audio->parent.rx_indicate(&audio->parent, len); } diff --git a/components/drivers/include/drivers/audio.h b/components/drivers/include/drivers/audio.h index e94c677368..70e837421b 100644 --- a/components/drivers/include/drivers/audio.h +++ b/components/drivers/include/drivers/audio.h @@ -1,98 +1,123 @@ +/* + * File : audio.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-05-09 Urey first version + */ + #ifndef __AUDIO_H__ #define __AUDIO_H__ -//#define AUDIO_DEVICE_USE_PRIVATE_BUFFER - - /* AUDIO command */ -#define _AUDIO_CTL(a) (0x10 + a) +#define _AUDIO_CTL(a) (0x10 + a) -#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1) -#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2) -#define AUDIO_CTL_SHUTDOWN _AUDIO_CTL(3) -#define AUDIO_CTL_START _AUDIO_CTL(4) -#define AUDIO_CTL_STOP _AUDIO_CTL(5) -#define AUDIO_CTL_PAUSE _AUDIO_CTL(6) -#define AUDIO_CTL_RESUME _AUDIO_CTL(7) -#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(8) -#define AUDIO_CTL_ALLOCBUFFER _AUDIO_CTL(9) -#define AUDIO_CTL_FREEBUFFER _AUDIO_CTL(10) -#define AUDIO_CTL_HWRESET _AUDIO_CTL(11) +#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1) +#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2) +#define AUDIO_CTL_SHUTDOWN _AUDIO_CTL(3) +#define AUDIO_CTL_START _AUDIO_CTL(4) +#define AUDIO_CTL_STOP _AUDIO_CTL(5) +#define AUDIO_CTL_PAUSE _AUDIO_CTL(6) +#define AUDIO_CTL_RESUME _AUDIO_CTL(7) +#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(8) +#define AUDIO_CTL_ALLOCBUFFER _AUDIO_CTL(9) +#define AUDIO_CTL_FREEBUFFER _AUDIO_CTL(10) +#define AUDIO_CTL_HWRESET _AUDIO_CTL(11) /* Audio Device Types */ -#define AUDIO_TYPE_QUERY 0x00 -#define AUDIO_TYPE_INPUT 0x01 -#define AUDIO_TYPE_OUTPUT 0x02 -#define AUDIO_TYPE_MIXER 0x04 -#define AUDIO_TYPE_SELECTOR 0x08 -#define AUDIO_TYPE_EFFECT 0x10 +#define AUDIO_TYPE_QUERY 0x00 +#define AUDIO_TYPE_INPUT 0x01 +#define AUDIO_TYPE_OUTPUT 0x02 +#define AUDIO_TYPE_MIXER 0x04 +#define AUDIO_TYPE_SELECTOR 0x08 +#define AUDIO_TYPE_EFFECT 0x10 /* Audio Format Types */ -#define AUDIO_FMT_PCM_U8 0x0001 -#define AUDIO_FMT_PCM_S8 0x0002 +#define AUDIO_FMT_PCM_U8 0x0001 +#define AUDIO_FMT_PCM_S8 0x0002 -#define AUDIO_FMT_PCM_U16_LE 0x0010 -#define AUDIO_FMT_PCM_S16_BE 0x0020 -#define AUDIO_FMT_PCM_S16_LE 0x0040 -#define AUDIO_FMT_PCM_U16_BE 0x0080 -#define AUDIO_FMT_PCM_U24_LE 0x0100 -#define AUDIO_FMT_PCM_S24_BE 0x0200 -#define AUDIO_FMT_PCM_S24_LE 0x0400 -#define AUDIO_FMT_PCM_U24_BE 0x0800 -#define AUDIO_FMT_PCM_U32_LE 0x1000 -#define AUDIO_FMT_PCM_S32_BE 0x2000 -#define AUDIO_FMT_PCM_S32_LE 0x4000 -#define AUDIO_FMT_PCM_U32_BE 0x8000 +#define AUDIO_FMT_PCM_U16_LE 0x0010 +#define AUDIO_FMT_PCM_S16_BE 0x0020 +#define AUDIO_FMT_PCM_S16_LE 0x0040 +#define AUDIO_FMT_PCM_U16_BE 0x0080 +#define AUDIO_FMT_PCM_U24_LE 0x0100 +#define AUDIO_FMT_PCM_S24_BE 0x0200 +#define AUDIO_FMT_PCM_S24_LE 0x0400 +#define AUDIO_FMT_PCM_U24_BE 0x0800 +#define AUDIO_FMT_PCM_U32_LE 0x1000 +#define AUDIO_FMT_PCM_S32_BE 0x2000 +#define AUDIO_FMT_PCM_S32_LE 0x4000 +#define AUDIO_FMT_PCM_U32_BE 0x8000 /* Supported Sampling Rates */ -#define AUDIO_SAMP_RATE_8K 0x0001 -#define AUDIO_SAMP_RATE_11K 0x0002 -#define AUDIO_SAMP_RATE_16K 0x0004 -#define AUDIO_SAMP_RATE_22K 0x0008 -#define AUDIO_SAMP_RATE_32K 0x0010 -#define AUDIO_SAMP_RATE_44K 0x0020 -#define AUDIO_SAMP_RATE_48K 0x0040 -#define AUDIO_SAMP_RATE_96K 0x0080 -#define AUDIO_SAMP_RATE_128K 0x0100 -#define AUDIO_SAMP_RATE_160K 0x0200 -#define AUDIO_SAMP_RATE_172K 0x0400 -#define AUDIO_SAMP_RATE_192K 0x0800 +#define AUDIO_SAMP_RATE_8K 0x0001 +#define AUDIO_SAMP_RATE_11K 0x0002 +#define AUDIO_SAMP_RATE_16K 0x0004 +#define AUDIO_SAMP_RATE_22K 0x0008 +#define AUDIO_SAMP_RATE_32K 0x0010 +#define AUDIO_SAMP_RATE_44K 0x0020 +#define AUDIO_SAMP_RATE_48K 0x0040 +#define AUDIO_SAMP_RATE_96K 0x0080 +#define AUDIO_SAMP_RATE_128K 0x0100 +#define AUDIO_SAMP_RATE_160K 0x0200 +#define AUDIO_SAMP_RATE_172K 0x0400 +#define AUDIO_SAMP_RATE_192K 0x0800 /* Supported Bit Rates */ -#define AUDIO_BIT_RATE_22K 0x01 -#define AUDIO_BIT_RATE_44K 0x02 -#define AUDIO_BIT_RATE_48K 0x04 -#define AUDIO_BIT_RATE_96K 0x08 -#define AUDIO_BIT_RATE_128K 0x10 -#define AUDIO_BIT_RATE_160K 0x20 -#define AUDIO_BIT_RATE_172K 0x40 -#define AUDIO_BIT_RATE_192K 0x80 +#define AUDIO_BIT_RATE_22K 0x01 +#define AUDIO_BIT_RATE_44K 0x02 +#define AUDIO_BIT_RATE_48K 0x04 +#define AUDIO_BIT_RATE_96K 0x08 +#define AUDIO_BIT_RATE_128K 0x10 +#define AUDIO_BIT_RATE_160K 0x20 +#define AUDIO_BIT_RATE_172K 0x40 +#define AUDIO_BIT_RATE_192K 0x80 /* Support Dsp(input/output) Units controls */ -#define AUDIO_DSP_PARAM 0 /* get/set all params */ -#define AUDIO_DSP_SAMPLERATE 1 /* 采样频率 */ -#define AUDIO_DSP_FMT 2 -#define AUDIO_DSP_CHANNELS 3 +#define AUDIO_DSP_PARAM 0 /* get/set all params */ +#define AUDIO_DSP_SAMPLERATE 1 /* 采样频率 */ +#define AUDIO_DSP_FMT 2 +#define AUDIO_DSP_CHANNELS 3 /* Supported Mixer Units controls */ -#define AUDIO_MIXER_QUERY 0x0000 -#define AUDIO_MIXER_MUTE 0x0001 -#define AUDIO_MIXER_VOLUME 0x0002 -#define AUDIO_MIXER_BASS 0x0004 -#define AUDIO_MIXER_MID 0x0008 -#define AUDIO_MIXER_TREBLE 0x0010 -#define AUDIO_MIXER_EQUALIZER 0x0020 -#define AUDIO_MIXER_LINE 0x0040 -#define AUDIO_MIXER_DIGITAL 0x0080 -#define AUDIO_MIXER_MIC 0x0100 +#define AUDIO_MIXER_QUERY 0x0000 +#define AUDIO_MIXER_MUTE 0x0001 +#define AUDIO_MIXER_VOLUME 0x0002 +#define AUDIO_MIXER_BASS 0x0004 +#define AUDIO_MIXER_MID 0x0008 +#define AUDIO_MIXER_TREBLE 0x0010 +#define AUDIO_MIXER_EQUALIZER 0x0020 +#define AUDIO_MIXER_LINE 0x0040 +#define AUDIO_MIXER_DIGITAL 0x0080 +#define AUDIO_MIXER_MIC 0x0100 -#define AUDIO_MIXER_EXTEND 0x8000 //extend mixer command +#define AUDIO_MIXER_EXTEND 0x8000 //extend mixer command + +#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4 +#define CFG_AUDIO_RECORD_PIPE_SIZE (8 * 1024) +#define AUDIO_DEVICE_MP_CNT (4) +#define AUDIO_DEVICE_DECODE_MP_BLOCK_SZ (4352 * 4) +#define AUDIO_DEVICE_DECODE_MP_SZ ((AUDIO_DEVICE_DECODE_MP_BLOCK_SZ*2 + 4)*AUDIO_DEVICE_MP_CNT) -#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4 -#define CFG_AUDIO_RECORD_PIPE_SIZE (8 * 1024) enum { @@ -104,36 +129,19 @@ enum /* the preferred number and size of audio pipeline buffer for the audio device */ struct rt_audio_buf_info { - rt_uint32_t buffer_size; /* Preferred qty of buffers */ - rt_uint32_t buffer_count; /* Preferred size of the buffers */ + rt_uint32_t buffer_size; /* Preferred qty of buffers */ + rt_uint32_t buffer_count; /* Preferred size of the buffers */ }; struct rt_audio_buf_desc { - rt_uint8_t *data_ptr; - rt_size_t data_size; + rt_uint8_t *data_ptr; + rt_size_t data_size; }; struct rt_audio_frame { const void *data_ptr; rt_size_t data_size; - rt_size_t data_ofs; -}; - -struct rt_audio_queue -{ - rt_uint16_t count; - rt_uint16_t size; - rt_uint16_t lwm; - rt_bool_t waiting_lwm; - - rt_uint16_t get_index; - rt_uint16_t put_index; - - struct rt_audio_frame *queue; - - rt_list_t suspended_push_list; - rt_list_t suspended_pop_list; }; struct rt_audio_device; @@ -141,25 +149,21 @@ struct rt_audio_caps; struct rt_audio_configure; struct rt_audio_ops { - rt_err_t (*getcaps) (struct rt_audio_device *audio,struct rt_audio_caps *caps); - rt_err_t (*configure) (struct rt_audio_device *audio,struct rt_audio_caps *caps); + rt_err_t (*getcaps) (struct rt_audio_device *audio,struct rt_audio_caps *caps); + rt_err_t (*configure) (struct rt_audio_device *audio,struct rt_audio_caps *caps); - rt_err_t (*init) (struct rt_audio_device *audio); - rt_err_t (*shutdown) (struct rt_audio_device *audio); - rt_err_t (*start) (struct rt_audio_device *audio,int stream); - rt_err_t (*stop) (struct rt_audio_device *audio,int stream); - rt_err_t (*suspend) (struct rt_audio_device *audio,int stream); - rt_err_t (*resume) (struct rt_audio_device *audio,int stream); + rt_err_t (*init) (struct rt_audio_device *audio); + rt_err_t (*shutdown) (struct rt_audio_device *audio); + rt_err_t (*start) (struct rt_audio_device *audio,int stream); + rt_err_t (*stop) (struct rt_audio_device *audio,int stream); + rt_err_t (*suspend) (struct rt_audio_device *audio,int stream); + rt_err_t (*resume) (struct rt_audio_device *audio,int stream); - rt_err_t (*control) (struct rt_audio_device *audio, rt_uint8_t cmd, void *arg); - rt_size_t (*transmit) (struct rt_audio_device *audio, const void *writeBuf,void *readBuf, rt_size_t size); + rt_err_t (*control) (struct rt_audio_device *audio, rt_uint8_t cmd, void *arg); + rt_size_t (*transmit) (struct rt_audio_device *audio, const void *writeBuf,void *readBuf, rt_size_t size); //get page size of codec or private buffer's info - void (*buffer_info) (struct rt_audio_device *audio,struct rt_audio_buf_info *info ); -#ifdef AUDIO_DEVICE_USE_PRIVATE_BUFFER - rt_err_t (*buffer_alloc) (struct rt_audio_device *audio,rt_uint8_t **data_ptr,rt_size_t *size); - void (*buffer_free) (struct rt_audio_device *audio,rt_uint8_t *data_ptr); -#endif + void (*buffer_info) (struct rt_audio_device *audio,struct rt_audio_buf_info *info ); }; @@ -174,42 +178,44 @@ struct rt_audio_configure struct rt_audio_caps { - int main_type; - int sub_type; + int main_type; + int sub_type; - union - { - rt_uint32_t mask; - int value; - struct rt_audio_configure config; - }udata; + union + { + rt_uint32_t mask; + int value; + struct rt_audio_configure config; + }udata; }; struct rt_audio_replay { rt_bool_t activated; - struct rt_audio_queue queue; + struct rt_data_queue queue; }; struct rt_audio_record { rt_bool_t activated; - struct rt_pipe_device pipe; + struct rt_pipe_device pipe; }; struct rt_audio_device { struct rt_device parent; - struct rt_audio_ops *ops; + struct rt_audio_ops *ops; - struct rt_audio_replay *replay; - struct rt_audio_record *record; + struct rt_mempool mp; + + struct rt_audio_replay *replay; + struct rt_audio_record *record; }; -rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data); -void rt_audio_tx_complete(struct rt_audio_device *audio,rt_uint8_t *pbuf); -void rt_audio_rx_done(struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len); -rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format); +rt_err_t rt_audio_register (struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data); +void rt_audio_tx_complete (struct rt_audio_device *audio,rt_uint8_t *pbuf); +void rt_audio_rx_done (struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len); +rt_uint32_t rt_audio_format_to_bits (rt_uint32_t format); /* Device Control Commands */ @@ -219,7 +225,6 @@ rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format); #define CODEC_CMD_SAMPLERATE 3 #define CODEC_CMD_EQ 4 #define CODEC_CMD_3D 5 -#define CODEC_CMD_SWITCH 6 #define CODEC_VOLUME_MAX (63)