0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于MM32F0163D7P的USB Audio Class(UAC)音频设备

冬至子 来源:灵动MM32MCU 作者:灵动MM32MCU 2023-09-01 16:40 次阅读

1 TinyUSB(UAC)音频简介

UAC是USB Audio Class的缩写,USB音频类,一个像USB这样的通用数据接口,可以有很多种实现数字音频数据传输的方式。不同的开发者可以根据自己的喜好和需求,定义任意的控制方式,传输模式,音频格式等等参数

在上一节我们在MM32F0163D7P 平台上成功的移植了TinyUSB,基于这个平台,今天我们来实现一个 uac2_headset 音频设备,这个设备支持基础的录音和放音功能,如果要支持音量调节/静音功能,还需要再添加一个 HID 变成复合设备。

2 快速移植一个UAC+HID复合设备

按照前面两篇文章,我们可以快速的移植出一个基于TinyUSB的UAC+HID复合设备,主要的代码片段如下:

/*------------- MAIN -------------*/
int main(void)
{
  USB_DeviceClockInit();//board_init();

  CONSOLE_Init(460800);  //enable printf debug

  // init device stack on configured roothub port
  tud_init(BOARD_TUD_RHPORT);

  TU_LOG1("UAC Headset & HID runningrn");   // CFG_TUSB_DEBUG for debugging #if CFG_TUSB_DEBUG
// 0 : no debug 
// 1 : print error
// 2 : print warning
// 3 : print info

  while (1)
  {
    tud_task(); // TinyUSB device task
    audio_task();
    hid_task();
  }

  return 0;
}
#define EPNUM_AUDIO_IN    0x01
#define EPNUM_AUDIO_OUT   0x01

#define EPNUM_HID   0x03


uint8_t const desc_configuration[] =
{
    // Interface count, string index, total length, attribute, power in mA
    TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),

    // Interface number, string index, EP Out & EP In address, EP size
    TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80),

    // Interface number, string index, protocol, report descriptor len, EP Out & In address, size & polling interval
    TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 6, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10), 

};
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+

// array of pointer to string descriptors
char const* string_desc_arr [] =
{
  (const char[]) { 0x09, 0x04 },  // 0: is supported language is English (0x0409)
  "TinyUSB",                      // 1: Manufacturer
  "TinyUSB headset",              // 2: Product
  "000001",                       // 3: Serials, should use chip ID
  "TinyUSB Speakers",             // 4: Audio Interface
  "TinyUSB Microphone",           // 5: Audio Interface
  "TinyUSB HID",                  // 6: HID Interface
};

image.png

图1 枚举过程

image.png

图2 枚举设备

工程文件树:

image.png

3 耳机设备设置修改音量

在耳机属性里面可以操作修改音量大小,同时通过抓包工具可以抓到主机下发的SET CUR命令。

image.png

图3 设置音量

4 耳机设备设置修改采样频率和位深度

在耳机属性高级里面默认格式可以看到下拉框有两种格式,一个是2通道 16位48000Hz,另外一个是2通道 24位 48000Hz,播放声音下发ISOC包的时候根据这个选择传输。

image.png

图4 设置采样频率和位深度

通过设置,下位机可以在播放或者录音时处理不同的采样频率和位深度。样例中全局变量current_resolution是位深度,current_sample_rate是采样频率。

5 音频数据的收发处理

播放时ISOC下发的数据包缓存在spk_buf里面。

录用时麦克风的声音采样数据写入mic_buf,通过ISOC同步上传到电脑端。(例程是将播放的数据包处理后通过接口又返回电脑端,由tud_audio_write((uint8_t * ) mic_buf, (uint16_t) (spk_data_size / 2))实现)

//--------------------------------------------------------------------+
// AUDIO Task
//--------------------------------------------------------------------+

void audio_task(void)
{
  // When new data arrived, copy data from speaker buffer, to microphone buffer
  // and send it over
  // Only support speaker & headphone both have the same resolution
  // If one is 16bit another is 24bit be care of LOUD noise !
  if (spk_data_size)
  {
    if (current_resolution == 16)         
    {
      int16_t *src = (int16_t*)spk_buf;
      int16_t *limit = (int16_t*)spk_buf + spk_data_size / 2;
      int16_t *dst = (int16_t*)mic_buf;
      while (src < limit)
      {
        // Combine two channels into one
        int32_t left = *src++;
        int32_t right = *src++;
        *dst++ = (int16_t) ((left > > 1) + (right > > 1));
      }
      memset(mic_buf,0xCC,sizeof(mic_buf));  //mm32 test code 
      tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2));
      spk_data_size = 0;
    }
    else if (current_resolution == 24)
    {
      int32_t *src = spk_buf;
      int32_t *limit = spk_buf + spk_data_size / 4;
      int32_t *dst = mic_buf;
      while (src < limit)
      {
        // Combine two channels into one
        int32_t left = *src++;
        int32_t right = *src++;
        *dst++ = (int32_t) ((uint32_t) ((left > > 1) + (right > > 1)) & 0xffffff00ul);
      }
      tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2));
      spk_data_size = 0;
    }
  }
}

6 功能验证测试

将uac2_headset 音频设备插入PC,在计算机管理->设备管理器->音频输入和输出里面出现耳机和麦克风两个TinyUSB headset设备证明枚举成功。

image.png

图5 设备管理器音频设备

电脑端播放音乐使用抓包工具抓到ISOC的数据包:

image.png

图6 ISOC数据包

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18298

    浏览量

    222273
  • 控制器
    +关注

    关注

    112

    文章

    15239

    浏览量

    171243
  • USB接口
    +关注

    关注

    9

    文章

    672

    浏览量

    54994
  • HID设备
    +关注

    关注

    0

    文章

    5

    浏览量

    6284
收藏 人收藏

    评论

    相关推荐

    USB序列号字符串被识别为两个USB音频设备

    时,它们可以被识别为两个USB音频设备,但是在MAC中只有一个USB音频设备被识别。我发现原因是,当我配置了UBFS时,序列号串的选择i选择了用户输入的文本(附加1)。EXT I将这个
    发表于 02-25 13:20

    USB音频设备没有得到任何数据

    我有一个FX2LP设计与一组描述符来创建一个USB音频设备。该设备实现了扬声器,所以我有一个USB流输入和扬声器输出。该设备被Windows
    发表于 05-30 08:10

    使用USB_Audio_Class进行语音设备设计时需要解决的音频信号同步问题是什么?

    不同方向的设计者进行开发,定义了不同的USB设备类(USB Device Class)。本文针对使用USB_Audio_Class进行语音
    发表于 06-08 06:32

    基于Linux内核的Rockchip USB Gadget UAC开发资料分享

    1、Rockchip USB Gadget UAC开发步骤本文档提供 Rockchip 平台基于 Linux 内核的 USB Gadget UAC
    发表于 08-10 16:03

    如何在imx8mp android 11 bsp上启用UVC+UAC复合小工具?

    我们正在使用 imx8mp android 11 bsp,我们想要启用 UVC+UAC 复合小工具功能,我们启用的内核配置: CONFIG_USB_CONFIGFS_F_UVC=y
    发表于 06-09 07:08

    USB音频设备的设计与实现

             在介绍USB 音频设备及其驱动程序结构的基础上,对USB Audio 功能节
    发表于 09-14 08:26 68次下载

    音频设备的规格

    音频设备的规格 规格简述主要是指各种音频设备的规格大小和设备功能,因为产品类型较多,所以此处只举两个重要一点的产品来说明:    
    发表于 01-07 11:47 704次阅读

    音频设备

    音频设备              音频设备主要是对音
    发表于 01-07 11:48 689次阅读

    音频设备类型

    音频设备类型              设备类型指音频设备的类型,就是音频设备属于功
    发表于 01-07 11:46 1759次阅读

    USB音频设备类的音频信号同步解决方案

    本文针对使用USB_Audio_Class进行语音设备设计时需要解决的音频 信号同步 问题进行了介绍,并给出了相应的解决方法和部分源代码。 引 言 USB总线协议经历了从
    发表于 10-26 14:52 9480次阅读
    <b class='flag-5'>USB</b><b class='flag-5'>音频设备</b>类的<b class='flag-5'>音频</b>信号同步解决方案

    音频设备中的幻象电源

    音频设备中的幻象电源
    发表于 10-28 12:00 0次下载
    <b class='flag-5'>音频设备</b>中的幻象电源

    基于MM32F0163D7P的I2S接口的音乐播放器实验

    I2S(Inter-IC Sound)总线,又称集成电路内置音频总线,是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准。
    发表于 07-12 11:42 704次阅读
    基于<b class='flag-5'>MM32F0163D7P</b>的I2S接口的音乐播放器实验

    基于MM32F0163D7PUSB接口TinyUSB应用:移植和新增设备(二)

    如果用户想增加一个device设备但是在TinyUSB class里面又没有参考示例,本次我们一起来移植一个CDC+printer复合设备。操作步骤还是和上篇一样,先将TinyUSB 从GitHub上克隆下来,将src 整个文件
    的头像 发表于 07-20 17:05 811次阅读
    基于<b class='flag-5'>MM32F0163D7P</b>的<b class='flag-5'>USB</b>接口TinyUSB应用:移植和新增<b class='flag-5'>设备</b>(二)

    基于MM32F0163D7PUSB Audio Class(UAC)音频设备

    UACUSB Audio Class的缩写,USB音频类,一个像
    的头像 发表于 07-27 16:34 674次阅读
    基于<b class='flag-5'>MM32F0163D7P</b>的<b class='flag-5'>USB</b> <b class='flag-5'>Audio</b> <b class='flag-5'>Class</b>(<b class='flag-5'>UAC</b>)<b class='flag-5'>音频设备</b>

    使用MPLAB Harmony在PIC32 MCU上创建USB音频设备

    电子发烧友网站提供《使用MPLAB Harmony在PIC32 MCU上创建USB音频设备.pdf》资料免费下载
    发表于 09-25 09:30 0次下载
    使用MPLAB Harmony在PIC32 MCU上创建<b class='flag-5'>USB</b><b class='flag-5'>音频设备</b>