|
本帖最后由 sunsili 于 2021-12-9 13:59 编辑
RT-Thread Audio - 1. 音频框架的分析
Github 上 RT-Thread 源码最新更新了关于 Audio 驱动相关的部分,让上层和底层都开发和编程简单了,不过对于大部分的开发者来说还不太熟悉这套框架的,那么笔者就这次编写音频驱动给大家分析下代码框架。
这里会先贴一张框架图,整个帖子都是笔者在编写开发过程中写的,可能有格式和错误,最终全部更新完毕后会整理整个系列的帖子。
1. RT-Thread 音频架构图
2. RT-Thread 音频框架的调用逻辑关系图(建议右键大图)
3. RT-Thread 音频应用代码模板(以wavplay为例)
https://github.com/RT-Thread-packages/wavplayer
4. RT-Thread 音频驱动代码模板
- #include "drv_sound.h"
- #include "drv_tina.h"
- #include "drivers/audio.h"
- #define DBG_TAG "drv_sound"
- #define DBG_LVL DBG_LOG
- #define DBG_COLOR
- #include
- #define TX_DMA_FIFO_SIZE (2048)
- struct temp_sound
- {
- struct rt_audio_device device;
- struct rt_audio_configure replay_config;
- int volume;
- rt_uint8_t *tx_fifo;
- };
- static rt_err_t getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data; (void)sound;
- return RT_EOK;
- }
- static rt_err_t configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data; (void)sound;
- return RT_EOK;
- }
- static rt_err_t init(struct rt_audio_device *audio)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data; (void)sound;
- return RT_EOK;
- }
- static rt_err_t start(struct rt_audio_device *audio, int stream)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data; (void)sound;
- return RT_EOK;
- }
- static rt_err_t stop(struct rt_audio_device *audio, int stream)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data; (void)sound;
- return RT_EOK;
- }
- rt_size_t transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data; (void)sound;
- return size;
- }
- static void buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
- {
- struct temp_sound *sound = RT_NULL;
- RT_ASSERT(audio != RT_NULL);
- sound = (struct temp_sound *)audio->parent.user_data;
- /**
- * TX_FIFO
- * +----------------+----------------+
- * | block1 | block2 |
- * +----------------+----------------+
- * \ block_size /
- */
- info->buffer = sound->tx_fifo;
- info->total_size = TX_DMA_FIFO_SIZE;
- info->block_size = TX_DMA_FIFO_SIZE / 2;
- info->block_count = 2;
- }
- static struct rt_audio_ops ops =
- {
- .getcaps = getcaps,
- .configure = configure,
- .init = init,
- .start = start,
- .stop = stop,
- .transmit = transmit,
- .buffer_info = buffer_info,
- };
- static int rt_hw_sound_init(void)
- {
- rt_uint8_t *tx_fifo = RT_NULL;
- static struct temp_sound sound = {0};
- /* 分配 DMA 搬运 buffer */
- tx_fifo = rt_calloc(1, TX_DMA_FIFO_SIZE);
- if(tx_fifo == RT_NULL)
- {
- return -RT_ENOMEM;
- }
- sound.tx_fifo = tx_fifo;
- /* 注册声卡放音驱动 */
- sound.device.ops = &ops;
- rt_audio_register(&sound.device, "sound0", RT_DEVICE_FLAG_WRONLY, &sound);
- return RT_EOK;
- }
- INIT_DEVICE_EXPORT(rt_hw_sound_init);
复制代码
5. 代码分析
待后续补充。。。
下载附件[sound_temp.7z]
|
+10
|