-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
changes proposal to audio feedback computation #1463
Conversation
Since the focus has changed from SOF to UAC feedback, I think we could add something to facilite feedback calculation based on FIFO count.
As I said earlier it's impossible to measure MCLK precisely with a MCU, also with @geekbozu's experimentation he also confirmed feedback value need to be tweaked with actual FIFO count. What do you think ? |
I think that would complete all possibilities to determine the feedback value! I think that would be awsome! Do you mean to add some option like |
Actually I'm not 100% sure if it should be based on SOF or not. All my tests were based on High-Speed which is easier to regulate the FIFO level, because frame interval is 125us instead of 1ms and less samples are arrived each packet. It's better to test with FS to see if my method works. Basically I took a FIFO size of 8*packet size and regulate the level to half full, which gives me a latency of 4*125us=0.5ms which is negligible. In FS the latency will be 4ms which should be okay, but the packet size will be 8 times larger. |
@HiFiPhile do you have an example code on how to calculate feedback on fifo count work ? I will try to find a way to fit it as well or give some option to do so. |
Full code is in https://github.com/HiFiPhile/i2s_bridge, UAC related code is in
My
|
thanks @HiFiPhile for sharing your code, I currently switch (yes) to another works. Give me a few days, I will try to update this PR-to-PR to include your feedback-on-fifo-count method. |
- also add interval_log2 to isr callback - also rename other variables
src/class/audio/audio_device.h
Outdated
enum { | ||
AUDIO_FEEDBACK_METHOD_DISABLED, | ||
AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, | ||
AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, | ||
AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, | ||
AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FIXED, | ||
AUDIO_FEEDBACK_METHOD_FIFO_COUNT_FLOAT | ||
}; | ||
|
||
typedef struct { | ||
uint8_t method; | ||
union { | ||
struct { | ||
uint32_t sample_freq; | ||
uint32_t mclk_freq; | ||
}frequency; | ||
|
||
struct { | ||
uint32_t nominal; | ||
uint32_t threshold; | ||
// variation etc .. | ||
}fifo_count; | ||
}; | ||
}audio_feedback_params_t; | ||
|
||
|
||
// TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HiFiPhile I made a draft idea on how to add the fifo count method, the params_cb with struct for input. Fifo count method seems to reply on a few params: std (nominal) value, variation, and buffer threshold. The buffer threshold is a bit tricky, since it requires application to respect this. The rest can be computed within the stack. Let me know if I miss something before adding the actual code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of union.
The buffer threshold is a bit tricky, since it requires application to respect this.
Yes indeed. It can be calculated in the stack because normally it's N*PacketSize, or add a macro for easier threshold calculation in application.
https://github.com/HiFiPhile/i2s_bridge/blob/1d6a24fdd0f70d150a88d85d63ed4b583b3b6b30/audio_callbacks.c#L186
Here 8000 is for HS (125us), FS need 1000.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad you like the idea. I am off for a few days, will put code together next week or so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HiFiPhile I have a silly question, fifo_count_flt
stands for float/fraction part in 16.16 format right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's "filtered" fifo count. As fifo count is jumpy each time a packet is arrived / consumed, it's hard to regulate the fifo level based on raw count. So I make an average of fifo count to get a stabilized value.
Basically fifo_count_flt = (fifo_count_old * 255 + fifo_count) / 256
, I shifted the whole value <<8 to let the result has enough precision so float is not required.
This value is well tested on HS for sample rate from 44.1kHz to 384kHz, but for FS another value may needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @HiFiPhile , I kind of getting the idea, filtered ~ average here
filtered = 255 * old + raw_count
feedback = nominal - (filtered/256 - threshold)
out of curiosity, how would you come up with the filtered/avg formula and how does it depend on sample rate, FS/HS link. Sorry for more question, I am trying to figure out the big picture and normalize the argument for this compute method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of curiosity, how would you come up with the filtered/avg formula and how does it depend on sample rate, FS/HS link.
I used J-Scope to watch FIFO level, it's kind of trial and error :)
FIFO is filled by USB packets and drained by I2S.
For the same sample rate, since HS packets arrive 8x faster every packet is 8x smaller, FIFO level variation is much smaller so easier to filter.
The higher the sample rate the higher the variation, in theory a higher filter coefficient is needed to achieve a same smoothed result.
But since feedback_std
is also proportional to sample rate, which cancelled the need of a higher filter coefficient.
So no need to change filter coefficient on sample rate change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the explanation, unfortunately, I still pretty much have no ideas how to generalize this into generic code. Apparently, there is no formula to fit all, I am just hoping to make some skeleton and allow user to simply tweaking a parameter or two with actual hardware. However, this is really out of my knowledge, and don't actually have any real application on hardware to test these out. This is purely due to my inexperience with audio
Since this has been pending for quite some time, I would like to merge this as it is and come back later to this later on. The good news is we have an decent API with place holders union for fifo count method (or any new method we could find afterwards). Should you have time feel free to make an PR to enhance this :)
Hi @HiFiPhile, I would be really interested to see your i2s_bridge repository for the fifo count feedback method. |
@Protoxy22 just sent you a invite:) |
Thank you ! |
Describe the PR
Proposal update to #1381