mirror of
https://github.com/hathach/tinyusb.git
synced 2026-03-29 19:03:34 +00:00
Implement RX FIFO threshold adjustment
Signed-off-by: HiFiPhile <admin@hifiphile.com>
This commit is contained in:
@ -35,13 +35,6 @@
|
||||
// MACRO CONSTANT TYPEDEF PROTOTYPES
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// List of supported sample rates for UAC2
|
||||
const uint32_t sample_rates[] = {44100, 48000, 88200, 96000};
|
||||
|
||||
#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
|
||||
|
||||
uint32_t current_sample_rate = 44100;
|
||||
|
||||
/* Blink pattern
|
||||
* - 25 ms : streaming data
|
||||
* - 250 ms : device not mounted
|
||||
@ -76,6 +69,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||
// Current states
|
||||
uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
|
||||
int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0
|
||||
uint32_t current_sample_rate = 44100;
|
||||
|
||||
// Buffer for speaker data
|
||||
uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 2];
|
||||
@ -316,6 +310,10 @@ static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#if TUD_OPT_HIGH_SPEED
|
||||
// List of supported sample rates for UAC2
|
||||
const uint32_t sample_rates[] = {44100, 48000, 88200, 96000};
|
||||
|
||||
#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
|
||||
|
||||
static bool audio20_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) {
|
||||
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
|
||||
@ -548,6 +546,17 @@ void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedba
|
||||
// Set feedback method to fifo counting
|
||||
feedback_param->method = AUDIO_FEEDBACK_METHOD_FIFO_COUNT;
|
||||
feedback_param->sample_freq = current_sample_rate;
|
||||
|
||||
// About FIFO threshold:
|
||||
//
|
||||
// By default the threshold is set to half FIFO size, which works well in most cases,
|
||||
// you can reduce the threshold to have less latency.
|
||||
//
|
||||
// For example, here we could set the threshold to 2 ms of audio data, as audio_task() read audio data every 1 ms,
|
||||
// having 2 ms threshold allows some margin and a quick response:
|
||||
//
|
||||
// feedback_param->fifo_count.fifo_threshold =
|
||||
// current_sample_rate * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX / 1000 * 2;
|
||||
}
|
||||
|
||||
#if CFG_AUDIO_DEBUG
|
||||
|
||||
@ -1546,7 +1546,7 @@ static bool audiod_fb_params_prepare(uint8_t func_id, uint8_t alt) {
|
||||
|
||||
// Prepare feedback computation if endpoint is available
|
||||
if (audio->ep_fb != 0) {
|
||||
audio_feedback_params_t fb_param;
|
||||
audio_feedback_params_t fb_param = {0};
|
||||
|
||||
tud_audio_feedback_params_cb(func_id, alt, &fb_param);
|
||||
audio->feedback.compute_method = fb_param.method;
|
||||
@ -1587,15 +1587,15 @@ static bool audiod_fb_params_prepare(uint8_t func_id, uint8_t alt) {
|
||||
} break;
|
||||
|
||||
case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: {
|
||||
// Initialize the threshold level to half filled
|
||||
uint16_t fifo_lvl_thr = tu_fifo_depth(&audio->ep_out_ff) / 2;
|
||||
audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_lvl_thr;
|
||||
audio->feedback.compute.fifo_count.fifo_lvl_avg = ((uint32_t) fifo_lvl_thr) << 16;
|
||||
// Determine FIFO threshold
|
||||
uint16_t fifo_threshold = fb_param.fifo_count.fifo_threshold ? fb_param.fifo_count.fifo_threshold : tu_fifo_depth(&audio->ep_out_ff) / 2;
|
||||
audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_threshold;
|
||||
audio->feedback.compute.fifo_count.fifo_lvl_avg = ((uint32_t) fifo_threshold) << 16;
|
||||
// Avoid 64bit division
|
||||
uint32_t nominal = ((fb_param.sample_freq / 100) << 16) / (frame_div / 100);
|
||||
audio->feedback.compute.fifo_count.nom_value = nominal;
|
||||
audio->feedback.compute.fifo_count.rate_const[0] = (uint16_t) ((audio->feedback.max_value - nominal) / fifo_lvl_thr);
|
||||
audio->feedback.compute.fifo_count.rate_const[1] = (uint16_t) ((nominal - audio->feedback.min_value) / fifo_lvl_thr);
|
||||
audio->feedback.compute.fifo_count.rate_const[0] = (uint16_t) ((audio->feedback.max_value - nominal) / fifo_threshold);
|
||||
audio->feedback.compute.fifo_count.rate_const[1] = (uint16_t) ((nominal - audio->feedback.min_value) / fifo_threshold);
|
||||
// On HS feedback is more sensitive since packet size can vary every MSOF, could cause instability
|
||||
if (tud_speed_get() == TUSB_SPEED_HIGH) {
|
||||
audio->feedback.compute.fifo_count.rate_const[0] /= 8;
|
||||
|
||||
@ -333,10 +333,12 @@ typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on
|
||||
}frequency;
|
||||
|
||||
} frequency;
|
||||
struct {
|
||||
uint16_t fifo_threshold; // Target FIFO threshold level, default to half FIFO if not set
|
||||
} fifo_count;
|
||||
};
|
||||
}audio_feedback_params_t;
|
||||
} audio_feedback_params_t;
|
||||
|
||||
// Invoked when needed to set feedback parameters
|
||||
void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param);
|
||||
|
||||
Reference in New Issue
Block a user