Add method to obtain precise audio sample rate based on hardware clocks #629
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Background
Currently libDaisy's getter methods to obtain the current audio codec sample rate as a float return the target/idealized sample rate – e.g.
48000.0
for 48kHz – when in fact the actual codec sample rate will be slightly different from this due to hardware limitations.The SAI peripheral clock must be divided by an integer (this is all initialized via the HAL) and thus the actual operating frame clock / LR clock (aka sample rate) for the I2S codec ends up being slightly off from the target sample rate. For example, at 48kHz target sample rate the actual operating sample rate comes out to ~
48014.324
.In many DSP applications this error doesn't matter. Oscillator tuning will be off only by a cent or so usually, and delay times etc are off by a marginal amount. However, for certain specific applications, the exact value is important, and it's good to have the option anyway. One such application is a looping delay (100% feedback delay line) which will drift over time if not using the correct value.
Changes
This PR adds a new method
GetPreciseSampleRate()
to SAI handle (also accessible via callthrough fromAudioHandle
) which provides the exact operating sample rate derived from the corresponding SAI peripheral clock and the HAL-determined MCK divider –Mckdiv
in the HAL init struct, as updated via the call toHAL_SAI_InitProtocol(...)
I also have my IDE setup to trim trailing whitespace and run clang-format (which uses the libDaisy configuration file) so there's a good amount of formatting changes here too.
Seeking Feedback:
GetSampleRate()
methods? This would not be an API-breaking change but it may have slight impact to existing applications so I didn't go that route.sai_idx
as an integer in theAudioHandle
method reasonable? It would also be easy, albeit more verbose, to useSAIHandle::Config::Peripheral
instead.Example Usage
Typical usage:
If the hardware is using an additional codec on the second SAI peripheral you can also specify this by passing
1
as an argument forsai_index
.