#include "uac_speaker.h"

//具体 funciton 实现， 以下为uac speaker 实现

#ifdef  DUAL_DENOISE_DEFINE
    #define AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT 2
#else
    #define AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT 1
#endif


#define AUDIO_V2_RANGE_VOL_NUM  1
#define AUDIO_V2_RANGE_SAMPLRATE_NUM  1

#define SPEAKER_CLK_UNIT_ID         1
#define SPEAKER_IN_TERMINAL_ID      2
#define SPEAKER_FU_TERMINAL_ID      3
#define SPEAKER_OUT_TERMINAL_ID     4

#define AUDIO_V2_ALTSETTING_16BIT       1
#define AUDIO_V2_ALTSETTING_24BIT       2
#define AUDIO_V2_ALTSETTING_32BIT       3

#define AUDIO_SPEAKER_V2_EP_MAX_PACKET_SIZE     512

#define AUDIO_SPEAKER_V2_BUFF_SIZE  2048


#define SPK_INTF_STR_INDEX 9

uint8_t uac_buff[1024] = {0};

static void _ep_data_out_handler(void *param, uint8_t ep_addr);


extern struct hal_usbd_ep_cb_struct hal_usbd_cb;

const static char *_ustring[] =
{
    "Language",
    "RT-Thread Team.",
    "RT-Thread Audio Speaker V2",
    "32021919830108",
    "Configuration",
    "Interface",
};


static struct udevice_descriptor dev_desc =
{
   USB_DESC_LENGTH_DEVICE,     //bLength;
   USB_DESC_TYPE_DEVICE,       //type;
   USB_BCD_VERSION,            //bcdUSB;
   USB_CLASS_AUDIO,           //bDeviceClass;
   0x00,                       //bDeviceSubClass;
   0x00,                       //bDeviceProtocol;
   64,                        //bMaxPacketSize0;
   _VENDOR_ID,                 //idVendor;
   _PRODUCT_ID,                //idProduct;
   USB_BCD_DEVICE,             //bcdDevice;
   USB_STRING_MANU_INDEX,      //iManufacturer;
   USB_STRING_PRODUCT_INDEX,   //iProduct;
   USB_STRING_SERIAL_INDEX,    //iSerialNumber;Unused.
   USB_DYNAMIC,                //bNumConfigurations;
};

static struct audio_v2_range_vol_block
{
   uint16_t wNumSubRanges;
   struct
   {
       uint16_t wMin;
       uint16_t wMax;
       uint16_t wRes;
   }__attribute__((packed)) subrange[AUDIO_V2_RANGE_VOL_NUM];
}__attribute__((packed));


static struct audio_v2_range_samplerate_block
{
   uint16_t wNumSubRanges;
   struct
   {
       uint32_t wMin;
       uint32_t wMax;
       uint32_t wRes;
   }__attribute__((packed)) subrange[AUDIO_V2_RANGE_SAMPLRATE_NUM];
}__attribute__((packed));

struct uac_audio_v2_speaker_as_info
{
   uint8_t                         buffer[AUDIO_SPEAKER_V2_BUFF_SIZE];
   volatile uint32_t               uac_recvcount;                  //rx接收的下标
   volatile int32_t                buffer_remain_size;             //
   volatile uint32_t               buffer_dma_transmit_start_pos;
   uep_t                           ep_streaming;
};

static struct uac_audio_v2_speaker_as_info speaker_as_info =
{
   {0},
   0,
   0,
   0,
   RT_NULL,
};

typedef  struct audio_v2_speaker_ac_info
{
	uint32_t speaker_bitwidth_cur;
#if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT ==1
   uint16_t speaker_volume_cur;         //用于支持单声道
#endif

#if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT ==2
   uint16_t speaker_volume_left_cur;
   uint16_t speaker_volume_right_cur;
#endif
   uint32_t speaker_samplerate_cur;
	struct audio_v2_range_vol_block speaker_volume_range;
   struct audio_v2_range_samplerate_block speaker_samplerate_range;
   uint8_t     ep0_buff[M_EP0_MAXP];
}__attribute__((packed));

static struct audio_v2_speaker_ac_info speaker_ac_info =
{
   16,
   #if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT ==1
       (255-30+1) << 8,//-30db
   #endif
   #if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT ==2
       ((255-30+1) << 8),//-30db     //-30的补码，后8位为小数点
       ((255-30+1) << 8),//-30db
   #endif

   16000,
   {
       1,          //only 1 range
       {
           {
               0xc400,     //min -60db
               0,          //max 0ddb
               0x0080,     //0.5*128 = 0.5db
           },
       },
   },
   {
       AUDIO_V2_RANGE_SAMPLRATE_NUM,
       {
           {
               16000,
               16000,
               0,
           },
       },
   },
   {0},
};




//描述符

static struct audio_v2_cs_if_ac_feature_unit_descriptor {
   uint8_t bLength;
   uint8_t bDescriptorType;
   uint8_t bDescriptorSubtype;
   uint8_t bUnitID;
   uint8_t bSourceID;
   uint32_t bmaControls[AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT+1];
   uint8_t iFeature;
} __attribute__((packed));

static struct audio_v2_ac_descriptor
{
#ifdef RT_USB_DEVICE_COMPOSITE
   struct uiad_descriptor iad_desc;
#endif
   struct uinterface_descriptor audio_v2_speaker_ac_intf_desc;
   //**************************** wtotalLength ****************************//
   struct audio_v2_cs_if_ac_header_descriptor          audio_v2_speaker_ac_header_desc;
   struct audio_v2_cs_if_ac_clock_source_descriptor    audio_v2_speaker_ac_clock;
   struct audio_v2_cs_if_ac_input_terminal_descriptor  audio_v2_speaker_ac_input_term;
   struct audio_v2_cs_if_ac_output_terminal_descriptor audio_v2_speaker_ac_output_term;
   struct audio_v2_cs_if_ac_feature_unit_descriptor    audio_v2_speaker_ac_fu_term;
   //*************************** *//
}__attribute__((packed));

static struct audio_v2_ac_descriptor ac_desc =
{
#ifdef RT_USB_DEVICE_COMPOSITE
   {
       USB_DESC_LENGTH_IAD,            // bLength;
       USB_DESC_TYPE_IAD,              // bDescriptorType;
       USB_DYNAMIC,                    // bFirstInterface;
       0x02,                           // bInterfaceCount;
       USB_CLASS_AUDIO,                // bFunctionClass;
       0x00,                           // bFunctionSubClass;
       0x20,                           // bFunctionProtocol;
       SPK_INTF_STR_INDEX,             // iFunction; 该function string 索引
   },
#endif
   {
       USB_DESC_LENGTH_INTERFACE,
       USB_DESC_TYPE_INTERFACE,
       USB_DYNAMIC,
       0x00,
       0x00,
       USB_CLASS_AUDIO,
       1,
       0x20,                       /*bInterfaceProtocol 描述USB版本*/
       0x00,

   },
   {
       sizeof(struct audio_v2_cs_if_ac_header_descriptor),
       AUDIO_INTERFACE_DESCRIPTOR_TYPE,
       AUDIO_CONTROL_HEADER,
       0x0200,
       AUDIO_CATEGORY_SPEAKER,
#ifndef RT_USB_DEVICE_COMPOSITE
       sizeof(struct audio_v2_ac_descriptor) - sizeof(struct uinterface_descriptor),
#else
       sizeof(struct audio_v2_ac_descriptor) - sizeof(struct uinterface_descriptor) - sizeof(struct uiad_descriptor),
#endif
       0,
   },
   {
       0x08,
       AUDIO_INTERFACE_DESCRIPTOR_TYPE,
       AUDIO_CONTROL_CLOCK_SOURCE,
       SPEAKER_CLK_UNIT_ID,
       0x07,
       0x07,
       0x00,
       0x00,
   },
   {
       0x11,                            /* bLength */
       AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
       AUDIO_CONTROL_INPUT_TERMINAL,    /* bDescriptorSubtype */
       SPEAKER_IN_TERMINAL_ID,          /* bTerminalID */
       AUDIO_TERMINAL_STREAMING,        /* wTerminalType : Microphone 0x0201 */
       0x00,                            /* bAssocTerminal */
       SPEAKER_CLK_UNIT_ID,             /* bCSourceID */
       AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT,                /* bNrChannels */
       0x00000003,                     /* wChannelConfig : Mono sets no position bits */
       0x00,                           /* iChannelNames */
       0x0000,                         /* bmControls */
       0x00  ,                         /* iTerminal */
   },
   {
       0x0c,                               /* bLength */
       AUDIO_INTERFACE_DESCRIPTOR_TYPE,    /* bDescriptorType */
       AUDIO_CONTROL_OUTPUT_TERMINAL,      /* bDescriptorSubtype */
       SPEAKER_OUT_TERMINAL_ID,            /* bTerminalID */
       AUDIO_OUTTERM_HEADPHONES,           /* wTerminalType : USB Streaming */
       SPEAKER_IN_TERMINAL_ID,             /* bAssocTerminal */    //input output terminal associate
       SPEAKER_FU_TERMINAL_ID,             /* bSourceID */
       SPEAKER_CLK_UNIT_ID,                /* bCSourceID */
       0x0000,                             /* bmControls */
       0x00                                /* iTerminal */

   },
   {
       AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT),     /* bLength */
       AUDIO_INTERFACE_DESCRIPTOR_TYPE,                            /* bDescriptorType */
       AUDIO_CONTROL_FEATURE_UNIT,                                 /* bDescriptorSubtype */
       SPEAKER_FU_TERMINAL_ID,                                     /* bUnitID */
       SPEAKER_IN_TERMINAL_ID,                                     /* bSourceID */
#if  AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 1
       {0x00000000,0x0000000c},                                    /* bmaControls(0) Mute */
#elif AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 2
       {0x00000000,0x0000000c,0x0000000c},
#endif
       0x00                             /* iTerminal */
   },
};

static struct audio_v2_as_descriptor
{
   struct uinterface_descriptor                audio_v2_speaker_as_intf_desc;
   struct audio_v2_cs_if_as_general_descriptor audio_v2_speaker_as_gener_desc;
   struct audio_v2_cs_if_as_format_descriptor  audio_v2_speaker_as_format_desc;
   struct audio_v2_cs_if_as_iso_ep_descriptor  audio_v2_speaker_as_isoep_desc;
   struct uendpoint_descriptor                 audio_v2_speaker_as_ep_streaming_desc;
#ifdef RT_USB_DEVICE_AUDIO_20_SPEAKER_ASYNCHRONOUS
   struct uendpoint_descriptor                 audio_v2_speaker_as_ep_feedback_desc;
#endif
}__attribute__((packed));


static struct uinterface_descriptor as_desc0 =
{
   USB_DESC_LENGTH_INTERFACE,
   USB_DESC_TYPE_INTERFACE,
   USB_DYNAMIC,
   0x00,
   0x00,
   USB_CLASS_AUDIO,
   2,
   0x20,
   0x00,
};

static struct audio_v2_as_descriptor as_desc_16bit =
{
   {
       USB_DESC_LENGTH_INTERFACE,
       USB_DESC_TYPE_INTERFACE,
       USB_DYNAMIC,
       AUDIO_V2_ALTSETTING_16BIT,
#ifndef RT_USB_DEVICE_AUDIO_20_SPEAKER_ASYNCHRONOUS
       0x01,
#else
       0x02,
#endif
       USB_CLASS_AUDIO,
       2,
       0x20,
       0x00,
   },
   {
       0x10,                            /* bLength */                                                                                                                        \
       AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */                                                                                                                \
       AUDIO_STREAMING_GENERAL,         /* bDescriptorSubtype */                                                                                                             \
       SPEAKER_IN_TERMINAL_ID,          /* bTerminalLink : Unit ID of the Output or Input Terminal*/                                                                         \
       0x00,                            /* bmControls */                                                                                                                     \
       AUDIO_FORMAT_TYPE_I,             /* bFormatType : AUDIO_FORMAT_TYPE_I */                                                                                              \
       0x00000001,                      /* bmFormats PCM */                                                                                                                  \
       AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT, /* bNrChannels */                                                                                                                    \
       0x00000003,                      /* bmChannelConfig */                                                                                                                \
       0x00,                            /* iChannelNames */
   },
   {
       0x06,                            /* bLength */                                                                                                                        \
       AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */                                                                                                                \
       AUDIO_STREAMING_FORMAT_TYPE,     /* bDescriptorSubtype */                                                                                                             \
       AUDIO_FORMAT_TYPE_I,             /* bFormatType */                                                                                                                    \
       2,                              /* bSubslotSize */                                                                                                                   \
       16,                             /* bBitResolution */
   },
   {
       0x08,
       AUDIO_ENDPOINT_DESCRIPTOR_TYPE,
       0x01,                           /** ep_general **/
       0x00,
       0x00,
       0x02,
       0x0002,
   },
   {
       USB_DESC_LENGTH_ENDPOINT,
       USB_DESC_TYPE_ENDPOINT,
       USB_DYNAMIC| USB_DIR_OUT,
#ifndef RT_USB_DEVICE_AUDIO_20_SPEAKER_ASYNCHRONOUS
       USB_EP_ATTR_ISOC,               //???同步应该是这个
#else
       USB_EP_ATTR_ISOC|(0x04),        //asynchronous
#endif
       AUDIO_SPEAKER_V2_EP_MAX_PACKET_SIZE,
       0x01,
   },
   #ifdef RT_USB_DEVICE_AUDIO_20_SPEAKER_ASYNCHRONOUS
   {
       USB_DESC_LENGTH_ENDPOINT,
       USB_DESC_TYPE_ENDPOINT,
       USB_DYNAMIC| USB_DIR_IN,
       USB_EP_ATTR_ISOC|(0x10),
       AUDIO_SPEAKER_V2_EP_FEEDBACK_MAX_PACKET_SIZE,
       0x04,
   },
   #endif
};
static rt_err_t _function_enable(ufunction_t func)
{
   return RT_EOK;
}

static rt_err_t _function_disable(ufunction_t func)
{
   return RT_EOK;
}
static struct ufunction_ops ops =
{
   _function_enable,
   _function_disable,
   RT_NULL,
};

static rt_err_t _audio_20_speaker_update_samplerate(udevice_t device, rt_size_t size)
{
    uep_t ep0;
    ep0 = &device->dcd->ep0;
    dcd_ep_read(device->dcd, EP0_OUT_ADDR, speaker_ac_info.ep0_buff);
    rt_memcpy(&speaker_ac_info.speaker_samplerate_cur,speaker_ac_info.ep0_buff,size);
    debug("speaker_ac_info.speaker_samplerate_cur = %d\n\r",speaker_ac_info.speaker_samplerate_cur);
   
    /* update dac samplerate */

    ep0->rx_indicate = RT_NULL;
    ep0->buffer = RT_NULL;
    return RT_EOK;
}

#if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 1
static rt_err_t _audio_20_speaker_update_vol(udevice_t device, rt_size_t size)
{
    uep_t ep0;
    ep0 = &device->dcd->ep0;
    dcd_ep_read(device->dcd, EP0_OUT_ADDR, speaker_ac_info.ep0_buff);
    rt_memcpy(&speaker_ac_info.speaker_volume_cur,speaker_ac_info.ep0_buff,size);
    debug("speaker_ac_info.speaker_volume_cur = %d\n\r",speaker_ac_info.speaker_volume_cur);
    ep0->rx_indicate = RT_NULL;
    ep0->buffer = RT_NULL;
}
#endif

#if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 2
static rt_err_t _audio_20_speaker_update_left_vol(udevice_t device, rt_size_t size)
{
    uep_t ep0;
    ep0 = &device->dcd->ep0;
    dcd_ep_read(device->dcd, EP0_OUT_ADDR, speaker_ac_info.ep0_buff);
    rt_memcpy(&speaker_ac_info.speaker_volume_left_cur,speaker_ac_info.ep0_buff,size);
    debug("speaker_ac_info.speaker_volume_left_cur = %d\n\r",speaker_ac_info.speaker_volume_left_cur);
    ep0->rx_indicate = RT_NULL;
    ep0->buffer = RT_NULL;
}
#endif
static void _interface_ac_handler(ufunction_t func, ureq_t setup)
{
    RT_ASSERT(func != RT_NULL);
    RT_ASSERT(func->device != RT_NULL);
    RT_ASSERT(setup != RT_NULL);
    if((setup->request_type & (0x01 << 7)) == 0x00 )
    {
        //host-device
        if((setup->request_type & (0x03)) == 0x01)  //确保interface setup
        {
            switch(setup->bRequest)
            {
                case AUDIO_REQUEST_CUR:
                    switch((setup->wIndex) >> 8)   //terminal 
                    {
                        case SPEAKER_FU_TERMINAL_ID:    //vol
                            #if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 1
                            rt_usbd_ep0_read(func->device, speaker_ac_info.ep0_buff, setup->wLength, _audio_20_speaker_update_vol);
                            #elif AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT ==2 
                            switch(setup->wValue & 0xFF)
                                {
                                    case 1:
                                        rt_usbd_ep0_read(func->device, speaker_ac_info.ep0_buff, setup->wLength, _audio_20_speaker_update_left_vol);
                                        break;
                                    case 2:
                                        rt_usbd_ep0_read(func->device, speaker_ac_info.ep0_buff, setup->wLength, _audio_20_speaker_update_left_vol);
                                        break;
                                    default :
                                        break;
                                }
                            #endif
                            break;
                        case SPEAKER_CLK_UNIT_ID:       //samplrate
                            rt_usbd_ep0_read(func->device, speaker_ac_info.ep0_buff, setup->wLength, _audio_20_speaker_update_samplerate);
                            //rt_event_send(speaker_as_info.event,EVENT_AUDIO_ASYNCHRONOUS_INIT);
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
        }
    }
    else
    {
        //device-host
        if((setup->request_type & (0x03)) == 0x01)
        {
            switch(setup->bRequest)
            {
                case AUDIO_REQUEST_CUR:
                    switch((setup->wIndex) >> 8)   //terminal 
                    {
                        //有点繁琐，一般来说两个耳机会是相同音量，但是为了避免未知的使用场景，如高音喇叭、低音喇叭这种，所以尽可能做得全面
                        case SPEAKER_FU_TERMINAL_ID:
                            #if AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 1
                                rt_usbd_ep0_write(func->device,&speaker_ac_info.speaker_volume_cur,setup->wLength);
                            #elif AUDIO_SPEAKER_V2_NUM_AUD_CHAN_OUT == 2 
                                switch(setup->wValue & 0xFF)
                                {
                                    case 1:
                                        rt_usbd_ep0_write(func->device,&speaker_ac_info.speaker_volume_left_cur,setup->wLength);
                                        break;
                                    case 2:
                                        rt_usbd_ep0_write(func->device,&speaker_ac_info.speaker_volume_right_cur,setup->wLength);
                                        break;
                                    default :
                                        break;
                                }
                            #endif
                            break;
                        case SPEAKER_CLK_UNIT_ID:
                            if(setup->wValue == 0x100)  //get cur samplerate
                            {
                                rt_usbd_ep0_write(func->device,&speaker_ac_info.speaker_samplerate_cur,setup->wLength);
                            }
                            else if(setup->wValue == 0x200) //get clk unit efftcive 
                            {
                                uint8_t temp_data = 1;
                                rt_usbd_ep0_write(func->device,&temp_data,setup->wLength);
                            }
                            
                            // hal_usbd_send(0, &speaker_ac_info.speaker_samplerate_cur, setup->wLength);
                            // debug("d 2 h ,hal,SPEAKER_CLK_UNIT_ID,wLength %d\n\r",setup->wLength);
                            break;
                        default:
                            break;
                    }
                    break;


                case AUDIO_REQUEST_RANGE:
                    //debug("get RANGE \n\r");
                    switch((setup->wIndex) >> 8)   //terminal 
                    {
                        case SPEAKER_FU_TERMINAL_ID:
                            rt_usbd_ep0_write(func->device,&speaker_ac_info.speaker_volume_range,setup->wLength);
                            //debug("get vol range\n\r");
                            break;
                        case SPEAKER_CLK_UNIT_ID:
                            rt_usbd_ep0_write(func->device,&speaker_ac_info.speaker_samplerate_range,setup->wLength);
                            //debug("get samplerate range\n\r");
                            break;
                        default:
                            break;
                    }
                    
                break;

                default:
                    break;
            }
        }
    }
    return RT_EOK;;
}

static uint16_t _ep_as_count = 0;
static void _interface_as_handler(ufunction_t func, ureq_t setup)
{
   //debug("ep_in\n\r");
   //hal_usbd_send(ep_addr, comp_hid_data.ep_in_buff, 2);
   //debug("_interface_as_handler\n\r");
   return;
}

static void _ep_data_out_handler(void *param, uint8_t ep_addr)
{
    _ep_as_count = hal_usbd_receive_count(ep_addr);

    hal_usbd_receive(ep_addr,uac_buff);
    dac_write_data((uint8_t *)uac_buff, _ep_as_count/2);
    return;
}

static void _ep_in_feedback_handler(void *param, uint8_t ep_addr)
{
    //debug("ep_in\n\r");
    //hal_usbd_read(ep_addr, comp_hid_data.ep_in_buff, 2);
    return;
}

/**
* This function will create a uac function instance.
*
* @param device the usb device object.
*
* @return RT_EOK on successful.
*/
ufunction_t rt_usbd_function_uac_speaker_create(udevice_t device)
{
   ufunction_t     func;
   uintf_t intf_ac, intf_as;
   ualtsetting_t   setting_ac,setting_as0,setting_as_16bit;
   struct audio_v2_as_descriptor *as_desc_t;

#ifdef RT_USB_DEVICE_COMPOSITE
   rt_usbd_device_set_interface_string(device, SPK_INTF_STR_INDEX, _ustring[2]);
#else
   /* set usb device string description */
   rt_usbd_device_set_string(device, _ustring);
#endif

   RT_ASSERT(device != RT_NULL);
   func = rt_usbd_function_new(device, &dev_desc, &ops);
    debug("uac create func 0x%x\n\r", func);
   intf_ac = rt_usbd_interface_new(device, _interface_ac_handler);
   intf_as = rt_usbd_interface_new(device, _interface_as_handler);

   setting_ac = rt_usbd_altsetting_new(sizeof(struct audio_v2_ac_descriptor));
   setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor));
   setting_as_16bit = rt_usbd_altsetting_new(sizeof(struct audio_v2_as_descriptor));

   rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc,
    (rt_off_t) & ((struct audio_v2_ac_descriptor *)0)->audio_v2_speaker_ac_intf_desc);
    rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0);
    
    rt_usbd_altsetting_config_descriptor(setting_as_16bit, &as_desc_16bit,
                                         (rt_off_t) & ((struct audio_v2_as_descriptor *)0)->audio_v2_speaker_as_intf_desc);

                                         /* create endpoint */
    as_desc_t = (struct audio_v2_as_descriptor *)setting_as_16bit->desc;

    speaker_as_info.ep_streaming = rt_usbd_endpoint_new(&as_desc_t->audio_v2_speaker_as_ep_streaming_desc, _ep_data_out_handler);       //RTT 端点框架不好，仅仅用16bit的描述符占用一下框架即可
#ifdef RT_USB_DEVICE_AUDIO_20_SPEAKER_ASYNCHRONOUS
    speaker_as_info.ep_feedback = rt_usbd_endpoint_new(&as_desc_t->audio_v2_speaker_as_ep_feedback_desc, _ep_in_feedback_handler);
#endif

    rt_usbd_altsetting_add_endpoint(setting_as_16bit,  speaker_as_info.ep_streaming);

    rt_usbd_interface_add_altsetting(intf_ac, setting_ac);
    rt_usbd_set_altsetting(intf_ac, 0);
    rt_usbd_interface_add_altsetting(intf_as, setting_as0);         
    rt_usbd_interface_add_altsetting(intf_as, setting_as_16bit);
    rt_usbd_set_altsetting(intf_as, 1);
    rt_usbd_function_add_interface(func, intf_ac);
    rt_usbd_function_add_interface(func, intf_as);

   return func;
}
