Skip to content

Commit ac3be8c

Browse files
committed
update(class/audio): change volume unit with dB, fix uac2.0 volume range
1 parent a72ecd2 commit ac3be8c

File tree

4 files changed

+53
-30
lines changed

4 files changed

+53
-30
lines changed

class/audio/usbd_audio.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,26 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
136136
memcpy(&volume, *data, *len);
137137
if (volume < 0x8000) {
138138
volume_db = volume / 256;
139-
} else if (volume > 0x8000) {
140-
volume_db = (0xffff - volume + 1) / -256;
139+
} else {
140+
volume_db = (volume - 0x10000) / 256;
141141
}
142-
volume_db += 128; /* 0 ~ 255 */
143-
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume);
142+
USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
144143
usbd_audio_set_volume(busid, ep, ch, volume_db);
145144
break;
146145
case AUDIO_REQUEST_GET_CUR:
147146
volume_db = usbd_audio_get_volume(busid, ep, ch);
148-
volume_db -= 128;
149147
if (volume_db >= 0) {
150148
volume = volume_db * 256;
151149
} else {
152-
volume = volume_db * 256 + 0xffff + 1;
150+
volume = volume_db * 256 + 0x10000;
153151
}
152+
USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
154153
memcpy(*data, &volume, 2);
155154
*len = 2;
156155
break;
157156
case AUDIO_REQUEST_GET_MIN:
158-
(*data)[0] = 0x00; /* -2560/256 dB */
159-
(*data)[1] = 0xdb;
157+
(*data)[0] = 0x00; /* -100 dB */
158+
(*data)[1] = 0x9c;
160159
*len = 2;
161160
break;
162161
case AUDIO_REQUEST_GET_MAX:
@@ -165,7 +164,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
165164
*len = 2;
166165
break;
167166
case AUDIO_REQUEST_GET_RES:
168-
(*data)[0] = 0x00; /* -256/256 dB */
167+
(*data)[0] = 0x00; /* 1 dB */
169168
(*data)[1] = 0x01;
170169
*len = 2;
171170
break;
@@ -178,22 +177,31 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup
178177
case AUDIO_REQUEST_CUR:
179178
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
180179
volume_db = usbd_audio_get_volume(busid, ep, ch);
181-
volume = volume_db;
180+
if (volume_db >= 0) {
181+
volume = volume_db * 256;
182+
} else {
183+
volume = volume_db * 256 + 0x10000;
184+
}
185+
USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
182186
memcpy(*data, &volume, 2);
183187
*len = 2;
184188
} else {
185189
memcpy(&volume, *data, *len);
186-
volume_db = volume;
187-
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume);
190+
if (volume < 0x8000) {
191+
volume_db = volume / 256;
192+
} else {
193+
volume_db = (volume - 0x10000) / 256;
194+
}
195+
USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db);
188196
usbd_audio_set_volume(busid, ep, ch, volume_db);
189197
}
190198
break;
191199
case AUDIO_REQUEST_RANGE:
192200
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
193201
*((uint16_t *)(*data + 0)) = 1;
194-
*((uint16_t *)(*data + 2)) = 0;
195-
*((uint16_t *)(*data + 4)) = 100;
196-
*((uint16_t *)(*data + 6)) = 1;
202+
*((uint16_t *)(*data + 2)) = 0x9c00; /* MIN -100 dB */
203+
*((uint16_t *)(*data + 4)) = 0x0000; /* MAX 0 dB */
204+
*((uint16_t *)(*data + 6)) = 0x100; /* RES 1 dB */
197205
*len = 8;
198206
} else {
199207
}
@@ -312,12 +320,12 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid,
312320
return intf;
313321
}
314322

315-
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume)
323+
__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db)
316324
{
317325
(void)busid;
318326
(void)ep;
319327
(void)ch;
320-
(void)volume;
328+
(void)volume_db;
321329
}
322330

323331
__WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch)

class/audio/usbd_audio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, struct usbd_interface
2727
void usbd_audio_open(uint8_t busid, uint8_t intf);
2828
void usbd_audio_close(uint8_t busid, uint8_t intf);
2929

30-
void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume);
30+
void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db);
3131
int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch);
3232
void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute);
3333
bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch);

class/audio/usbh_audio.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,21 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
184184
return ret;
185185
}
186186

187-
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume)
187+
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db)
188188
{
189189
struct usb_setup_packet *setup;
190190
int ret;
191191
uint8_t feature_id = 0xff;
192192
uint8_t intf;
193193
uint16_t volume_hex;
194-
uint16_t volume_max;
195-
uint16_t volume_add;
194+
int volume_min_db;
195+
int volume_max_db;
196196

197197
if (!audio_class || !audio_class->hport) {
198198
return -USB_ERR_INVAL;
199199
}
200200

201-
if (volume > 100) {
201+
if ((volume_db > 127) || (volume_db < -127)) {
202202
return -USB_ERR_INVAL;
203203
}
204204

@@ -271,15 +271,30 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint
271271
setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf;
272272
setup->wLength = 2;
273273

274-
/* change volume range start with zero */
275-
volume_add = 0x10000 - audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min;
276-
volume_max = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max + volume_add;
277-
volume_hex = volume * volume_max / 100.0;
274+
if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min < 0x8000) {
275+
volume_min_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min / 256;
276+
} else {
277+
volume_min_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min - 0x10000) / 256;
278+
}
279+
280+
if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max < 0x8000) {
281+
volume_max_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max / 256;
282+
} else {
283+
volume_max_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max - 0x10000) / 256;
284+
}
285+
286+
USB_LOG_INFO("Get ch:%d dB range: %d dB ~ %d dB\r\n", volume_min_db, volume_max_db);
278287

279-
if (volume_hex >= volume_add) {
280-
volume_hex = volume_hex - volume_add;
288+
if (volume_db >= 0) {
289+
volume_hex = volume_db * 256;
290+
if (volume_hex > audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max) {
291+
return -USB_ERR_RANGE;
292+
}
281293
} else {
282-
volume_hex = 0x10000 - (volume_add - volume_hex);
294+
volume_hex = volume_db * 256 + 0x10000;
295+
if (volume_hex < audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min) {
296+
return -USB_ERR_RANGE;
297+
}
283298
}
284299

285300
memcpy(g_audio_buf, &volume_hex, 2);

class/audio/usbh_audio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extern "C" {
5959

6060
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution);
6161
int usbh_audio_close(struct usbh_audio *audio_class, const char *name);
62-
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume);
62+
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db);
6363
int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute);
6464

6565
void usbh_audio_run(struct usbh_audio *audio_class);

0 commit comments

Comments
 (0)