-
Notifications
You must be signed in to change notification settings - Fork 137
Compensate for resampler latency where it is utilized #531
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -658,9 +658,9 @@ cbjack_get_max_channel_count(cubeb * /*ctx*/, uint32_t * max_channels) | |
| } | ||
|
|
||
| static int | ||
| cbjack_get_latency(cubeb_stream * stm, unsigned int * latency_ms) | ||
| cbjack_get_latency(cubeb_stream * stm, unsigned int * latency) | ||
| { | ||
| *latency_ms = stm->context->jack_latency; | ||
| *latency = stm->context->jack_latency + ceil(cubeb_resampler_latency(stm->resampler) * stm->ratio); | ||
| return CUBEB_OK; | ||
| } | ||
|
|
||
|
|
@@ -955,7 +955,7 @@ cbjack_stream_stop(cubeb_stream * stream) | |
| static int | ||
| cbjack_stream_get_position(cubeb_stream * stream, uint64_t * position) | ||
| { | ||
| *position = stream->position; | ||
| *position = stream->position - ceil(cubeb_resampler_latency(stream->resampler) * stream->ratio); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will underflow on stream start, you want to branch here and return 0 if this would be negative: if the stream has just started, it's still filling the buffers in the underlying layer, and nothing is being output. Because |
||
| return CUBEB_OK; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2596,12 +2596,15 @@ int wasapi_stream_get_position(cubeb_stream * stm, uint64_t * position) | |
| return CUBEB_ERROR; | ||
| } | ||
|
|
||
| double resample_ratio = stream_to_mix_samplerate_ratio(stm->output_stream_params, stm->output_mix_params); | ||
|
|
||
| /* Calculate how far behind the current stream head the playback cursor is. */ | ||
| uint64_t stream_delay = static_cast<uint64_t>(current_stream_delay(stm) * stm->output_stream_params.rate); | ||
| uint64_t resampler_delay = ceil(cubeb_resampler_latency(stm->resampler.get()) * resample_ratio); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is tricky. |
||
| uint64_t stream_delay = static_cast<uint64_t>((current_stream_delay(stm) * stm->output_stream_params.rate)) + resampler_delay; | ||
|
|
||
| /* Calculate the logical stream head in frames at the stream sample rate. */ | ||
| uint64_t max_pos = stm->total_frames_written + | ||
| static_cast<uint64_t>(round(stm->frames_written * stream_to_mix_samplerate_ratio(stm->output_stream_params, stm->output_mix_params))); | ||
| static_cast<uint64_t>(round(stm->frames_written * resample_ratio)); | ||
|
|
||
| *position = max_pos; | ||
| if (stream_delay <= *position) { | ||
|
|
@@ -2637,13 +2640,18 @@ int wasapi_stream_get_latency(cubeb_stream * stm, uint32_t * latency) | |
| if (FAILED(hr)) { | ||
| return CUBEB_ERROR; | ||
| } | ||
|
|
||
|
|
||
| double resample_ratio = stream_to_mix_samplerate_ratio(stm->output_stream_params, stm->output_mix_params); | ||
| uint32_t resample_latency = ceil(cubeb_resampler_latency(stm->resampler.get()) * resample_ratio); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same logic applies here. |
||
|
|
||
| // This happens on windows 10: no error, but always 0 for latency. | ||
| if (latency_hns == 0) { | ||
| double delay_s = current_stream_delay(stm); | ||
| // convert to sample-frames | ||
| *latency = delay_s * stm->output_stream_params.rate; | ||
| // convert to output(mix) rate sample-frames | ||
| *latency = (delay_s * stm->output_mix_params.rate) + resample_latency; | ||
| } else { | ||
| *latency = hns_to_frames(stm, latency_hns); | ||
| *latency = hns_to_frames(stm, latency_hns) + resample_latency; | ||
| } | ||
|
|
||
| return CUBEB_OK; | ||
|
|
@@ -2664,7 +2672,11 @@ int wasapi_stream_get_input_latency(cubeb_stream * stm, uint32_t * latency) | |
| return CUBEB_ERROR; | ||
| } | ||
|
|
||
| *latency = hns_to_frames(stm, stm->input_latency_hns); | ||
|
|
||
| double resample_ratio = stream_to_mix_samplerate_ratio(stm->output_stream_params, stm->output_mix_params); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is input latency, and the input mix rate is frequently different from the output rate (for example because the microphone and the output device are two separate devices, that have been configured with different rates: this is sub-optimal, but happens). |
||
| uint32_t resample_latency = ceil(cubeb_resampler_latency(stm->resampler.get()) * resample_ratio); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It appears that you can't write this function with the current API: In general there is some work needed on the resampler, that became very clear when working on https://github.com/kinetiknz/cubeb/pull/598 |
||
|
|
||
| *latency = hns_to_frames(stm, stm->input_latency_hns) + resample_latency; | ||
|
|
||
| return CUBEB_OK; | ||
| } | ||
|
|
||
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.
This is already in logical stream rate, no need to adjust.