You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as
// The interval value audio->fb_n_frames was taken from the descriptors within audiod_set_interface()
2024
2039
2040
+
// n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed - this lower limit ensures the measures feedback value has sufficient precision
// f_m max is 2^29/(1 ms * n_frames) for full speed and 2^29/(125 us * n_frames) for high speed, this means for f_m fitting in an uint32, n_frames must be < 125 for full speed and < 1000 for high speed (1000 does not fit into uint8 so the maximum possible value cannot even be reached by UAC2 - we don't need to check for it)
2065
+
2066
+
if ((f_s> (2^19)-1) || (TUSB_SPEED_FULL==tud_speed_get() && (audio->fb_n_frames>125)))
2033
2067
{
2034
-
// Next best option is to use float if a FPU is available - this has to be enabled by the user
audio->feedback_param_factor_D=0; // non zero marks float option
2039
-
}
2040
-
else
2041
-
{
2042
-
// Neither a power of two or floats - use fixed point number
2043
-
audio->feedback_param_factor_N.i=f_s << 13;
2044
-
audio->feedback_param_factor_D=f_m*n_frame;
2045
-
}
2068
+
// If this check fails, not every thing is lost - you need to re-evaluate the scaling factors of the parameters such that the numbers fit into uint64 again. feedback = n_cycles * S_c / (n_frames * S_n) * f_s * S_s / (f_m * S_m). In the end S_c*S_s / (S_n * S_m) = 2^16 for a 16.16 fixed point precision. If you find something, define your own function of tud_audio_set_feedback_params_fm_fs() and audiod_sof() and use your values
2069
+
TU_LOG2(" FEEDBACK_DETERMINATION_MODE_FIXED_POINT not possible!\r\n"); TU_BREAKPOINT(); return false;
// Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec
2061
2089
// Boiled down, the feedback value Ff = n_samples / (micro)frame.
2062
-
// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_cpu is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s)
2063
-
// The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_cpu / f_s)), K)
2064
-
// Ff = n_cycles / n_frames * f_s / f_cpu in 16.16 format, where n_cycles are the number of CPU cycles within n_frames
2090
+
// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s)
2091
+
// The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K)
2092
+
// feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames
2065
2093
2066
2094
// Iterate over audio functions and set feedback value
2067
2095
for(uint8_ti=0; i<CFG_TUD_AUDIO; i++)
2068
-
{
2069
-
audiod_function_t*audio=&_audiod_fct[i];
2096
+
{
2097
+
audiod_function_t*audio=&_audiod_fct[i];
2070
2098
2071
-
if (audio->ep_fb!=0)
2099
+
if (audio->ep_fb!=0)
2100
+
{
2101
+
audio->fb_n_frames_current++;
2102
+
if (audio->fb_n_frames_current==audio->fb_n_frames)
if (as_itf!=audio->ep_in_as_intf_num&&as_itf!=audio->ep_out_as_intf_num) return; // Abort, this interface has no EP, this driver does not support this currently
if (as_itf!=audio->ep_in_as_intf_num&&as_itf!=audio->ep_out_as_intf_num) break; // Abort loop, this interface has no EP, this driver does not support this currently
#error You must tell the driver the feedback determination mode! Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT!
#error Unknown CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE. Possible choices are: CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_POWER_OF_TWO_SHIFT, CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FLOAT, or CFG_TUD_AUDIO_ENABLE_FEEDBACK_DETERMINATION_MODE_FIXED_POINT!
213
+
#endif
214
+
#endif
215
+
216
+
#endif
217
+
199
218
// Audio interrupt control EP size - disabled if 0
200
219
#ifndefCFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
201
220
#defineCFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74)
// p_cycle_count : Pointer to main clock cycle counter register where the current count can be read from (e.g. a timer register)
510
+
511
+
// This function must be called from the user within the tud_audio_set_itf_cb(rhport, p_request) callback function, where p_request needs to be checked as
0 commit comments