diff --git a/class/audio/usbd_audio.c b/class/audio/usbd_audio.c index 4ff3767a..458f1c19 100644 --- a/class/audio/usbd_audio.c +++ b/class/audio/usbd_audio.c @@ -136,27 +136,26 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup memcpy(&volume, *data, *len); if (volume < 0x8000) { volume_db = volume / 256; - } else if (volume > 0x8000) { - volume_db = (0xffff - volume + 1) / -256; + } else { + volume_db = (volume - 0x10000) / 256; } - volume_db += 128; /* 0 ~ 255 */ - USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume); + USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); usbd_audio_set_volume(busid, ep, ch, volume_db); break; case AUDIO_REQUEST_GET_CUR: volume_db = usbd_audio_get_volume(busid, ep, ch); - volume_db -= 128; if (volume_db >= 0) { volume = volume_db * 256; } else { - volume = volume_db * 256 + 0xffff + 1; + volume = volume_db * 256 + 0x10000; } + USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); memcpy(*data, &volume, 2); *len = 2; break; case AUDIO_REQUEST_GET_MIN: - (*data)[0] = 0x00; /* -2560/256 dB */ - (*data)[1] = 0xdb; + (*data)[0] = 0x00; /* -100 dB */ + (*data)[1] = 0x9c; *len = 2; break; case AUDIO_REQUEST_GET_MAX: @@ -165,7 +164,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup *len = 2; break; case AUDIO_REQUEST_GET_RES: - (*data)[0] = 0x00; /* -256/256 dB */ + (*data)[0] = 0x00; /* 1 dB */ (*data)[1] = 0x01; *len = 2; break; @@ -178,22 +177,31 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup case AUDIO_REQUEST_CUR: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { volume_db = usbd_audio_get_volume(busid, ep, ch); - volume = volume_db; + if (volume_db >= 0) { + volume = volume_db * 256; + } else { + volume = volume_db * 256 + 0x10000; + } + USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); memcpy(*data, &volume, 2); *len = 2; } else { memcpy(&volume, *data, *len); - volume_db = volume; - USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume); + if (volume < 0x8000) { + volume_db = volume / 256; + } else { + volume_db = (volume - 0x10000) / 256; + } + USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); usbd_audio_set_volume(busid, ep, ch, volume_db); } break; case AUDIO_REQUEST_RANGE: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { *((uint16_t *)(*data + 0)) = 1; - *((uint16_t *)(*data + 2)) = 0; - *((uint16_t *)(*data + 4)) = 100; - *((uint16_t *)(*data + 6)) = 1; + *((uint16_t *)(*data + 2)) = 0x9c00; /* MIN -100 dB */ + *((uint16_t *)(*data + 4)) = 0x0000; /* MAX 0 dB */ + *((uint16_t *)(*data + 6)) = 0x100; /* RES 1 dB */ *len = 8; } else { } @@ -312,12 +320,12 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, return intf; } -__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume) +__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db) { (void)busid; (void)ep; (void)ch; - (void)volume; + (void)volume_db; } __WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch) diff --git a/class/audio/usbd_audio.h b/class/audio/usbd_audio.h index 442405a2..75a0b17d 100644 --- a/class/audio/usbd_audio.h +++ b/class/audio/usbd_audio.h @@ -27,7 +27,7 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, struct usbd_interface void usbd_audio_open(uint8_t busid, uint8_t intf); void usbd_audio_close(uint8_t busid, uint8_t intf); -void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume); +void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db); int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch); void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute); bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch); diff --git a/class/audio/usbh_audio.c b/class/audio/usbh_audio.c index 53090e18..6d8b4559 100644 --- a/class/audio/usbh_audio.c +++ b/class/audio/usbh_audio.c @@ -184,21 +184,21 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) return ret; } -int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume) +int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db) { struct usb_setup_packet *setup; int ret; uint8_t feature_id = 0xff; uint8_t intf; uint16_t volume_hex; - uint16_t volume_max; - uint16_t volume_add; + int volume_min_db; + int volume_max_db; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; } - if (volume > 100) { + if ((volume_db > 127) || (volume_db < -127)) { return -USB_ERR_INVAL; } @@ -271,15 +271,30 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; setup->wLength = 2; - /* change volume range start with zero */ - volume_add = 0x10000 - audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min; - volume_max = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max + volume_add; - volume_hex = volume * volume_max / 100.0; - - if (volume_hex >= volume_add) { - volume_hex = volume_hex - volume_add; + if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min < 0x8000) { + volume_min_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min / 256; } else { - volume_hex = 0x10000 - (volume_add - volume_hex); + volume_min_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min - 0x10000) / 256; + } + + if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max < 0x8000) { + volume_max_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max / 256; + } else { + volume_max_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max - 0x10000) / 256; + } + + USB_LOG_INFO("Get ch:%d dB range: %d dB ~ %d dB\r\n", volume_min_db, volume_max_db); + + if (volume_db >= 0) { + volume_hex = volume_db * 256; + if (volume_hex > audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max) { + return -USB_ERR_RANGE; + } + } else { + volume_hex = volume_db * 256 + 0x10000; + if (volume_hex < audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min) { + return -USB_ERR_RANGE; + } } memcpy(g_audio_buf, &volume_hex, 2); diff --git a/class/audio/usbh_audio.h b/class/audio/usbh_audio.h index 5af38ca2..2e583ac0 100644 --- a/class/audio/usbh_audio.h +++ b/class/audio/usbh_audio.h @@ -59,7 +59,7 @@ extern "C" { int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution); int usbh_audio_close(struct usbh_audio *audio_class, const char *name); -int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume); +int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db); int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute); void usbh_audio_run(struct usbh_audio *audio_class);