From cb906c90b8edb93b1dcae0b69ee295fe63a7717c Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Thu, 11 Aug 2022 17:27:00 +0800 Subject: [PATCH] fix clock source process in uac2.0 --- class/audio/usbd_audio.c | 86 ++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/class/audio/usbd_audio.c b/class/audio/usbd_audio.c index 8c1b05bd..2201d175 100644 --- a/class/audio/usbd_audio.c +++ b/class/audio/usbd_audio.c @@ -52,23 +52,22 @@ struct usbd_audio_attribute_control { uint32_t mute_bCUR; struct audio_v2_control_range2_param_block_default volume; uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; - uint32_t sampling_freq[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; }; #endif struct audio_entity_info { usb_slist_t list; uint8_t bDescriptorSubtype; uint8_t bEntityId; - void *priv; + void *priv[2]; }; static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head); const uint8_t default_sampling_freq_table[] = { - AUDIO_SAMPLE_FREQ_NUM(5), - AUDIO_SAMPLE_FREQ_4B(8000), - AUDIO_SAMPLE_FREQ_4B(8000), - AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_NUM(1), + // AUDIO_SAMPLE_FREQ_4B(8000), + // AUDIO_SAMPLE_FREQ_4B(8000), + // AUDIO_SAMPLE_FREQ_4B(0x00), AUDIO_SAMPLE_FREQ_4B(16000), AUDIO_SAMPLE_FREQ_4B(16000), AUDIO_SAMPLE_FREQ_4B(0x00), @@ -81,15 +80,15 @@ const uint8_t default_sampling_freq_table[] = { AUDIO_SAMPLE_FREQ_4B(48000), AUDIO_SAMPLE_FREQ_4B(48000), AUDIO_SAMPLE_FREQ_4B(0x00), - // AUDIO_SAMPLE_FREQ_4B(88200), - // AUDIO_SAMPLE_FREQ_4B(88200), - // AUDIO_SAMPLE_FREQ_4B(0x00), - // AUDIO_SAMPLE_FREQ_4B(96000), - // AUDIO_SAMPLE_FREQ_4B(96000), - // AUDIO_SAMPLE_FREQ_4B(0x00), - // AUDIO_SAMPLE_FREQ_4B(192000), - // AUDIO_SAMPLE_FREQ_4B(192000), - // AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(88200), + AUDIO_SAMPLE_FREQ_4B(88200), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(96000), + AUDIO_SAMPLE_FREQ_4B(96000), + AUDIO_SAMPLE_FREQ_4B(0x00), + AUDIO_SAMPLE_FREQ_4B(192000), + AUDIO_SAMPLE_FREQ_4B(192000), + AUDIO_SAMPLE_FREQ_4B(0x00), }; #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 @@ -144,7 +143,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * setup->bRequest); struct audio_entity_info *current_entity_info = NULL; - struct usbd_audio_attribute_control *current_control = NULL; + struct usbd_audio_attribute_control *current_feature_control = NULL; + uint32_t *sampling_freq; usb_slist_t *i; uint8_t entity_id; uint8_t control_selector; @@ -175,7 +175,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * return -2; } - current_control = (struct usbd_audio_attribute_control *)current_entity_info->priv; + current_feature_control = (struct usbd_audio_attribute_control *)current_entity_info->priv[0]; + sampling_freq = (uint32_t *)current_entity_info->priv[1]; if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) { #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 @@ -186,12 +187,12 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * switch (setup->bRequest) { case AUDIO_REQUEST_SET_CUR: mute = (*data)[0]; - current_control->mute[ch] = mute; + current_feature_control->mute[ch] = mute; USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]); usbd_audio_set_mute(entity_id, ch, mute); break; case AUDIO_REQUEST_GET_CUR: - (*data)[0] = current_control->mute[ch]; + (*data)[0] = current_feature_control->mute[ch]; break; default: USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest); @@ -203,7 +204,7 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * switch (setup->bRequest) { case AUDIO_REQUEST_SET_CUR: volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0])); - current_control->volume[ch].vol_current = volume; + current_feature_control->volume[ch].vol_current = volume; if (volume < 0x8000) { volume2db = 0.00390625 * volume; @@ -215,27 +216,27 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * usbd_audio_set_volume(entity_id, ch, volume2db); break; case AUDIO_REQUEST_GET_CUR: - memcpy(*data, ¤t_control->volume[ch].vol_current, 2); + memcpy(*data, ¤t_feature_control->volume[ch].vol_current, 2); *len = 2; break; case AUDIO_REQUEST_GET_MIN: - memcpy(*data, ¤t_control->volume[ch].vol_min, 2); + memcpy(*data, ¤t_feature_control->volume[ch].vol_min, 2); *len = 2; break; case AUDIO_REQUEST_GET_MAX: - memcpy(*data, ¤t_control->volume[ch].vol_max, 2); + memcpy(*data, ¤t_feature_control->volume[ch].vol_max, 2); *len = 2; break; case AUDIO_REQUEST_GET_RES: - memcpy(*data, ¤t_control->volume[ch].vol_res, 2); + memcpy(*data, ¤t_feature_control->volume[ch].vol_res, 2); *len = 2; break; case AUDIO_REQUEST_SET_RES: - memcpy(¤t_control->volume[ch].vol_res, *data, 2); + memcpy(¤t_feature_control->volume[ch].vol_res, *data, 2); *len = 2; break; default: @@ -253,7 +254,7 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * switch (control_selector) { case AUDIO_FU_CONTROL_MUTE: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - (*data)[0] = current_control->mute_bCUR; + (*data)[0] = current_feature_control->mute_bCUR; *len = 1; } else { mute = (*data)[0]; @@ -263,12 +264,12 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * break; case AUDIO_FU_CONTROL_VOLUME: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - (*data)[0] = current_control->volume_bCUR & 0XFF; - (*data)[1] = (current_control->volume_bCUR >> 8) & 0xff; + (*data)[0] = current_feature_control->volume_bCUR & 0XFF; + (*data)[1] = (current_feature_control->volume_bCUR >> 8) & 0xff; *len = 2; } else { volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0])); - current_control->volume_bCUR = volume; + current_feature_control->volume_bCUR = volume; USB_LOG_DBG("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume); usbd_audio_set_volume(entity_id, ch, volume); } @@ -282,10 +283,10 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * switch (control_selector) { case AUDIO_FU_CONTROL_VOLUME: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - *((uint16_t *)(*data + 0)) = current_control->volume.wNumSubRanges; - *((uint16_t *)(*data + 2)) = current_control->volume.subrange[ch].wMin; - *((uint16_t *)(*data + 4)) = current_control->volume.subrange[ch].wMax; - *((uint16_t *)(*data + 6)) = current_control->volume.subrange[ch].wRes; + *((uint16_t *)(*data + 0)) = current_feature_control->volume.wNumSubRanges; + *((uint16_t *)(*data + 2)) = current_feature_control->volume.subrange[ch].wMin; + *((uint16_t *)(*data + 4)) = current_feature_control->volume.subrange[ch].wMax; + *((uint16_t *)(*data + 6)) = current_feature_control->volume.subrange[ch].wRes; *len = 8; } else { } @@ -309,15 +310,12 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * switch (control_selector) { case AUDIO_CS_CONTROL_SAM_FREQ: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - uint32_t current_sampling_freq = current_control->sampling_freq[ch]; - memcpy(*data, ¤t_sampling_freq, sizeof(uint32_t)); + memcpy(*data, &sampling_freq[ch], sizeof(uint32_t)); *len = 4; } else { - uint32_t sampling_freq; - memcpy(&sampling_freq, *data, setup->wLength); - current_control->sampling_freq[ch] = sampling_freq; - USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq); - usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq); + memcpy(&sampling_freq[ch], *data, setup->wLength); + USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]); + usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq[ch]); } break; case AUDIO_CS_CONTROL_CLOCK_VALID: @@ -439,13 +437,17 @@ void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype) control->volume.subrange[ch].wMax = 100; control->volume.subrange[ch].wRes = 1; control->mute[ch] = 0; - control->sampling_freq[ch] = 16000; control->volume_bCUR = 50; control->mute_bCUR = 0; } #endif - entity_info->priv = control; + entity_info->priv[0] = control; } else if (bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) { + uint32_t *sampling_freq = usb_malloc(sizeof(uint32_t) * CONFIG_USBDEV_AUDIO_MAX_CHANNEL); + for (size_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) { + sampling_freq[ch] = 16000; + } + entity_info->priv[1] = sampling_freq; } usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list);