RT-Thread Audio - 1. 音频框架的分析

发布于 2019-11-09 13:42:58
    本帖最后由 liu2guang 于 2019-11-9 13:48 编辑


Github 上 RT-Thread 源码最新更新了关于 Audio 驱动相关的部分,让上层和底层都开发和编程简单了,不过对于大部分的开发者来说还不太熟悉这套框架的,那么笔者就这次编写音频驱动给大家分析下代码框架。

这里会先贴一张框架图,整个帖子都是笔者在编写开发过程中写的,可能有格式和错误,最终全部更新完毕后会整理整个系列的帖子。

1. RT-Thread 音频架构图

RT-Thread Audio Framework 架构图.png

2. RT-Thread 音频框架的调用逻辑关系图(建议右键大图)

[img=5100,5426][/img]

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]




查看更多

关注者
0
被浏览
1.8k
8 个回答
来一颗糖
来一颗糖 2019-11-09
前排围观 9 层音频驱动框架。。。:lol
whj467467222
whj467467222 认证专家 2019-11-09
前排围观 9 层音频驱动框架。。。
charlown.cai
charlown.cai 2019-11-10
第二张逻辑关系图显示不出来,一直在打转
XQQ
XQQ 2019-11-19
啥时候继续更新
liu2guang
liu2guang 认证专家 2019-11-19
XQQ 发表于 2019-11-19 11:06
啥时候继续更新


周末更新,最近事情比较多,会更新一个系列的,这个帖子比较笔记,写的比较水
qz_rtt
qz_rtt 2019-11-26
不赖,加油,加点文字说明一下,不然新手可能比较迷惑。
HappyTime
HappyTime 2020-05-03
liu2guang 发表于 2019-11-11 09:54
直接点击这个图片链接试试,图片比较大

https://note.youdao.com/yws/public/resource/7fdf0aa9ba116fe1 ...


链接也不好使了。。。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览