Skip to content
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

Please clarify use as ASRC #1

Open
timsurber opened this issue Jul 20, 2023 · 3 comments
Open

Please clarify use as ASRC #1

timsurber opened this issue Jul 20, 2023 · 3 comments

Comments

@timsurber
Copy link

Hey,

thank you for your work!

Could you please explain how to use your library as ASRC (asynchronous sample rate converter) .

Imagine I have two threads, one is pushing new samples in, the other receives them at non synchronous clocks.

Your library would be in the middle.

Which functions would I call?

Which parameters would be static and which should be varied in the servo loop? I would imagine ratio, but what about numInputFrames and numOutputFrames?

Thank you!

@dbry
Copy link
Owner

dbry commented Jul 21, 2023

First, let me apologize for not having any function-level documentation on the resampler; I really must rectify that! Especially for implementing an ASRC, the demo application is not sufficient.

For an ASRC, the only parameter that would be controlled in the servo loop is the ratio, and the only function you would call (once you got started) would be resampleProcess() (or resampleProcessInterleaved() depending on your data layout).

The numInputFrames and numOutputFrames simply indicate to the function how many samples are available at input and how much writable space is available at output. In other words, the process function just continues to convert (at the given ratio) until either the available input or available output is exhausted (and both input samples used and output samples generated are returned). Of course, if you are operating directly on ring buffers then you might need multiple calls to account for wrapping, but the normal use would be to process as much data as possible, as long as there’s space for the result.

The crudest design I can imagine for an ASRC is where you have one large ring buffer that receives the resampled data (to head) and outputs to the destination (from tail). In that case the buffer level directly controls the ratio: as the buffer level drops the ratio is increased, which causes the resampled data to flow into the buffer faster. The buffer could also hold audio before it's resampled too, either way is pretty much equivalent.

Of course, this simple case is complicated by the fact that the data might be arriving (and leaving) in chunks, so unless the buffer is many times the size of the chunks (which means high latency) then it becomes more complex to gauge the “fullness” unless there is timestamp information along with the chunks. In other words, by knowing when the last chunks arrived and left, it's possible to create a much more accurate estimate for the actual fullness.

In the most exacting case where precise sample timestamping is available, then it is possible to make very small adjustments to the ratio and correct for the difference in a single small buffer (i.e., a “tight” servo). However, for this to work well it is desireable to get subsample position information from the resampler, and that’s what the resampleGetPosition() function is for. Let me know if you need more help with that (it’s not documented at all), although probably by the time a sample-accurate version is working without this, it will be obvious to you what you need.

I have found that ASRC applications can vary quite a lot with respect to their requirements and implementations, so it’s difficult to answer too specifically. But I hope this helps you get a feeling for how this library might be used. If something is not clear or you need more guidance, please feel free to ask.

@timsurber
Copy link
Author

Thank you this helps really a lot!

@dbry
Copy link
Owner

dbry commented Jul 22, 2023

Great!

I have just added function-level documentation as promised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants