Add callback to to set feedback format correction at runtime.
This commit is contained in:
@@ -329,7 +329,7 @@ typedef struct
|
|||||||
|
|
||||||
uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS)
|
uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS)
|
||||||
uint8_t compute_method;
|
uint8_t compute_method;
|
||||||
|
bool format_correction;
|
||||||
union {
|
union {
|
||||||
uint8_t power_of_2; // pre-computed power of 2 shift
|
uint8_t power_of_2; // pre-computed power of 2 shift
|
||||||
float float_const; // pre-computed float constant
|
float float_const; // pre-computed float constant
|
||||||
@@ -484,6 +484,11 @@ TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf,
|
|||||||
(void) alt_itf;
|
(void) alt_itf;
|
||||||
feedback_param->method = AUDIO_FEEDBACK_METHOD_DISABLED;
|
feedback_param->method = AUDIO_FEEDBACK_METHOD_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TU_ATTR_WEAK bool tud_audio_feedback_format_correction_cb(uint8_t func_id) {
|
||||||
|
(void) func_id;
|
||||||
|
return CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift) {
|
TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift) {
|
||||||
@@ -1211,9 +1216,9 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
|
|||||||
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
||||||
static inline bool audiod_fb_send(audiod_function_t *audio)
|
static inline bool audiod_fb_send(audiod_function_t *audio)
|
||||||
{
|
{
|
||||||
|
bool apply_correction = TUSB_SPEED_FULL == tud_speed_get() && audio->feedback.format_correction;
|
||||||
// Format the feedback value
|
// Format the feedback value
|
||||||
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION
|
if (apply_correction)
|
||||||
if ( TUSB_SPEED_FULL == tud_speed_get() )
|
|
||||||
{
|
{
|
||||||
uint8_t * fb = (uint8_t *) &audio->feedback.send_buf;
|
uint8_t * fb = (uint8_t *) &audio->feedback.send_buf;
|
||||||
|
|
||||||
@@ -1221,17 +1226,12 @@ static inline bool audiod_fb_send(audiod_function_t *audio)
|
|||||||
*(fb++) = (audio->feedback.value >> 2) & 0xFF;
|
*(fb++) = (audio->feedback.value >> 2) & 0xFF;
|
||||||
*(fb++) = (audio->feedback.value >> 10) & 0xFF;
|
*(fb++) = (audio->feedback.value >> 10) & 0xFF;
|
||||||
*(fb++) = (audio->feedback.value >> 18) & 0xFF;
|
*(fb++) = (audio->feedback.value >> 18) & 0xFF;
|
||||||
// 4th byte is needed to work correctly with MS Windows
|
|
||||||
*fb = 0;
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
value = audio->feedback.value;
|
audio->feedback.send_buf = audio->feedback.value;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
audio->feedback.send_buf = audio->feedback.value;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, 4);
|
return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, apply_correction ? 3 : 4);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2018,6 +2018,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
|
|||||||
tud_audio_feedback_params_cb(func_id, alt, &fb_param);
|
tud_audio_feedback_params_cb(func_id, alt, &fb_param);
|
||||||
audio->feedback.compute_method = fb_param.method;
|
audio->feedback.compute_method = fb_param.method;
|
||||||
|
|
||||||
|
if(TUSB_SPEED_FULL == tud_speed_get())
|
||||||
|
audio->feedback.format_correction = tud_audio_feedback_format_correction_cb(func_id);
|
||||||
|
|
||||||
// Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame)
|
// Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame)
|
||||||
uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000;
|
uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000;
|
||||||
audio->feedback.min_value = ((fb_param.sample_freq - 1)/frame_div) << 16;
|
audio->feedback.min_value = ((fb_param.sample_freq - 1)/frame_div) << 16;
|
||||||
|
@@ -193,6 +193,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable/disable conversion from 16.16 to 10.14 format on full-speed devices. See tud_audio_n_fb_set().
|
// Enable/disable conversion from 16.16 to 10.14 format on full-speed devices. See tud_audio_n_fb_set().
|
||||||
|
// Can be override by tud_audio_feedback_format_correction_cb()
|
||||||
#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION
|
#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION
|
||||||
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1
|
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1
|
||||||
#endif
|
#endif
|
||||||
@@ -491,8 +492,8 @@ void tud_audio_fb_done_cb(uint8_t func_id);
|
|||||||
// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed.
|
// This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed.
|
||||||
//
|
//
|
||||||
// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default,
|
// The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default,
|
||||||
// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set
|
// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set or tud_audio_feedback_format_correction_cb()
|
||||||
// then tinyusb expects 16.16 format and handles the conversion to 10.14 on FS.
|
// return true, then tinyusb expects 16.16 format and handles the conversion to 10.14 on FS.
|
||||||
//
|
//
|
||||||
// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and it seems the
|
// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and it seems the
|
||||||
// driver can work with either format.
|
// driver can work with either format.
|
||||||
@@ -545,6 +546,9 @@ void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedba
|
|||||||
// interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor
|
// interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor
|
||||||
TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift);
|
TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift);
|
||||||
|
|
||||||
|
// (Full-Speed only) Callback to set feedback format correction is applied or not,
|
||||||
|
// default to CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION if not implemented.
|
||||||
|
bool tud_audio_feedback_format_correction_cb(uint8_t func_id);
|
||||||
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
||||||
|
|
||||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||||
|
Reference in New Issue
Block a user