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

Add async OfflineAudioContext startRendering, suspend and resume #412

Merged
merged 14 commits into from
Dec 27, 2023

Conversation

orottier
Copy link
Owner

@orottier orottier commented Dec 18, 2023

Todo:

  • Decide if we like the sync interface this way
  • Check if it solves our node-binding issues
  • Address performance regression (caused by checking the need to suspend every quantum)

It is a temporary fix because this simplifies the node bindings.

As long as OfflineContext rendering is synchronous, the bounds are not
necessary. The tests fail however because we require OfflineAudioContext
to be Send and Sync. To be dealt with later.
@orottier orottier requested a review from b-ma December 18, 2023 13:00
@orottier orottier marked this pull request as ready for review December 19, 2023 08:14
@orottier
Copy link
Owner Author

/bench

@orottier
Copy link
Owner Author

I'm ready for a first round of reviews!

@orottier orottier changed the base branch from feature/offline-audiocontext-suspend to main December 19, 2023 08:16
Copy link

Benchmark result:


bench_ctor
  Instructions:             4834095 (+7.381739%)
  L1 Accesses:              7115981 (+4.337098%)
  L2 Accesses:                54213 (+0.053521%)
  RAM Accesses:               61610 (+0.146294%)
  Estimated Cycles:         9543396 (+3.235431%)

bench_audio_buffer_decode
  Instructions:             7583979 (+0.015931%)
  L1 Accesses:             10486128 (+0.013496%)
  L2 Accesses:                28779 (+2.256254%)
  RAM Accesses:               32108 (+0.202852%)
  Estimated Cycles:        11753803 (+0.058441%)

bench_sine
  Instructions:            70190484 (+0.498650%)
  L1 Accesses:            102320868 (+0.313792%)
  L2 Accesses:               274844 (+4.070126%)
  RAM Accesses:               62435 (+0.091378%)
  Estimated Cycles:       105880313 (+0.356203%)

bench_sine_gain
  Instructions:            77886507 (+0.473110%)
  L1 Accesses:            114049511 (+0.322369%)
  L2 Accesses:               296223 (+1.814089%)
  RAM Accesses:               62544 (+0.083211%)
  Estimated Cycles:       117719666 (+0.336407%)

bench_sine_gain_delay
  Instructions:           148566909 (+0.250902%)
  L1 Accesses:            208996035 (+0.178256%)
  L2 Accesses:               553637 (+5.249380%)
  RAM Accesses:               64110 (+0.076490%)
  Estimated Cycles:       214008070 (+0.239660%)

bench_buffer_src
  Instructions:            17191676 (+2.057787%)
  L1 Accesses:             25134826 (+1.316148%)
  L2 Accesses:                89374 (+2.693324%)
  RAM Accesses:              100618 (+0.094506%)
  Estimated Cycles:        29103326 (+1.187545%)

bench_buffer_src_delay
  Instructions:            89532637 (+0.403761%)
  L1 Accesses:            122695000 (+0.289408%)
  L2 Accesses:               171350 (+7.141964%)
  RAM Accesses:              100758 (+0.089403%)
  Estimated Cycles:       127078280 (+0.327105%)

bench_buffer_src_iir
  Instructions:            41195769 (+0.876089%)
  L1 Accesses:             60180206 (+0.584839%)
  L2 Accesses:                93576 (+5.678276%)
  RAM Accesses:              100711 (+0.095413%)
  Estimated Cycles:        64172971 (+0.593171%)

bench_buffer_src_biquad
  Instructions:            36599448 (+1.071761%)
  L1 Accesses:             51835355 (+0.754643%)
  L2 Accesses:               152500 (+21.62927%)
  RAM Accesses:              100833 (+0.080395%)
  Estimated Cycles:        56127010 (+0.947246%)

bench_stereo_positional
  Instructions:            41540301 (+1.179850%)
  L1 Accesses:             62517411 (+0.833830%)
  L2 Accesses:               294999 (+38.52255%)
  RAM Accesses:              100919 (+0.093231%)
  Estimated Cycles:        67524571 (+1.397208%)

bench_stereo_panning_automation
  Instructions:            31431873 (+1.177044%)
  L1 Accesses:             47328965 (+0.781241%)
  L2 Accesses:               137568 (+2.690275%)
  RAM Accesses:              100740 (+0.095386%)
  Estimated Cycles:        51542705 (+0.759009%)

bench_analyser_node
  Instructions:            39200181 (+0.890530%)
  L1 Accesses:             55052904 (+0.563759%)
  L2 Accesses:               216339 (+18.77687%)
  RAM Accesses:              101218 (+0.042501%)
  Estimated Cycles:        59677229 (+0.812775%)

bench_hrtf_panners
  Instructions:           329398763 (-0.058205%)
  L1 Accesses:            577696263 (-0.036090%)
  L2 Accesses:             10901323 (+0.319677%)
  RAM Accesses:              120734 (+0.199180%)
  Estimated Cycles:       636428568 (-0.004160%)

bench_sine_gain_with_worklet
  Instructions:            78688865 (+0.435170%)
  L1 Accesses:            115120949 (+0.245965%)
  L2 Accesses:               350642 (+17.58697%)
  RAM Accesses:               62722 (+0.060622%)
  Estimated Cycles:       119069429 (+0.460679%)


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s


@b-ma
Copy link
Collaborator

b-ma commented Dec 19, 2023

Ok cool! I will try to have a closer look this week, and (hopefully) try to see where this gets us with the bindings

/// assert_eq!(buffer.number_of_channels(), 1);
/// assert_eq!(buffer.length(), 512);
/// ```
pub async fn suspend_at(&self, suspend_time: f64) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could just call it suspend as there is no alternative signature

/// ```
pub async fn suspend_at(&self, suspend_time: f64) {
let quantum = (suspend_time * self.base.sample_rate() as f64 / RENDER_QUANTUM_SIZE as f64)
.ceil() as usize;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should check the other conditions as well, cf. https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-suspend, but maybe for another PR (this one may be a bit tricky "is less than or equal to the current time"

/// assert_eq!(buffer.number_of_channels(), 1);
/// assert_eq!(buffer.length(), 512);
/// ```
pub fn suspend_at_sync<F: FnOnce(&mut Self) + Send + Sync + 'static>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, maybe suspend_sync is clear enough?

@b-ma
Copy link
Collaborator

b-ma commented Dec 21, 2023

Hey, except my small comments, look all good to me! I will try to implement the bindings, I let you know

@orottier
Copy link
Owner Author

Thanks for the comments. I will address those, plus the leftover performance regression.

@orottier
Copy link
Owner Author

/bench

Copy link

Benchmark result:


bench_ctor
  Instructions:             4241334 (-5.786007%)
  L1 Accesses:              6376860 (-6.500725%)
  L2 Accesses:                54213 (+0.059061%)
  RAM Accesses:               61578 (+0.097532%)
  Estimated Cycles:         8803155 (-4.771653%)

bench_audio_buffer_decode
  Instructions:             7583867 (+0.014190%)
  L1 Accesses:             10485577 (+0.008698%)
  L2 Accesses:                29090 (+3.071963%)
  RAM Accesses:               32084 (+0.131078%)
  Estimated Cycles:        11753967 (+0.057179%)

bench_sine
  Instructions:            69605257 (-0.339323%)
  L1 Accesses:            101593592 (-0.398625%)
  L2 Accesses:               266805 (+0.778488%)
  RAM Accesses:               62408 (+0.040075%)
  Estimated Cycles:       105111897 (-0.374778%)

bench_sine_gain
  Instructions:            77297552 (-0.286679%)
  L1 Accesses:            113284087 (-0.359078%)
  L2 Accesses:               307623 (+9.207383%)
  RAM Accesses:               62514 (+0.027201%)
  Estimated Cycles:       117010192 (-0.236997%)

bench_sine_gain_delay
  Instructions:           147951561 (-0.164348%)
  L1 Accesses:            208188499 (-0.203123%)
  L2 Accesses:               547090 (+1.694506%)
  RAM Accesses:               64082 (+0.021852%)
  Estimated Cycles:       213166819 (-0.176858%)

bench_buffer_src
  Instructions:            16606585 (-1.415837%)
  L1 Accesses:             24399924 (-1.646812%)
  L2 Accesses:                89104 (+2.502042%)
  RAM Accesses:              100580 (+0.054713%)
  Estimated Cycles:        28365744 (-1.375968%)

bench_buffer_src_delay
  Instructions:            88921182 (-0.282061%)
  L1 Accesses:            121902465 (-0.358029%)
  L2 Accesses:               165783 (+3.289015%)
  RAM Accesses:              100732 (+0.055624%)
  Estimated Cycles:       126257000 (-0.323416%)

bench_buffer_src_iir
  Instructions:            40607017 (-0.565715%)
  L1 Accesses:             59434108 (-0.664808%)
  L2 Accesses:                90401 (+3.865023%)
  RAM Accesses:              100672 (+0.054663%)
  Estimated Cycles:        63409633 (-0.594184%)

bench_buffer_src_biquad
  Instructions:            36010656 (-0.554411%)
  L1 Accesses:             51094906 (-0.692995%)
  L2 Accesses:               128633 (+6.209954%)
  RAM Accesses:              100809 (+0.047637%)
  Estimated Cycles:        55266386 (-0.570799%)

bench_stereo_positional
  Instructions:            40948566 (-0.292134%)
  L1 Accesses:             61818469 (-0.282605%)
  L2 Accesses:               184730 (-23.11822%)
  RAM Accesses:              100892 (+0.055536%)
  Estimated Cycles:        66273339 (-0.675881%)

bench_stereo_panning_automation
  Instructions:            30843055 (-0.718423%)
  L1 Accesses:             46575640 (-0.822199%)
  L2 Accesses:               140755 (+4.781437%)
  RAM Accesses:              100701 (+0.057629%)
  Estimated Cycles:        50803950 (-0.688042%)

bench_analyser_node
  Instructions:            38622782 (-0.595570%)
  L1 Accesses:             54351116 (-0.709522%)
  L2 Accesses:               187080 (+0.075426%)
  RAM Accesses:              101213 (+0.032615%)
  Estimated Cycles:        58828971 (-0.652750%)

bench_hrtf_panners
  Instructions:           329573002 (-0.008992%)
  L1 Accesses:            577886116 (-0.005466%)
  L2 Accesses:             10856560 (-0.160052%)
  RAM Accesses:              120827 (+0.238095%)
  Estimated Cycles:       636397861 (-0.017056%)

bench_sine_gain_with_worklet
  Instructions:            78125883 (-0.283434%)
  L1 Accesses:            114454804 (-0.339012%)
  L2 Accesses:               299786 (+2.459414%)
  RAM Accesses:               62706 (+0.035097%)
  Estimated Cycles:       118148444 (-0.297538%)


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s


@orottier
Copy link
Owner Author

Cool, the baseline performance regression is gone and even exceeds performance of the previous release. I guess due to ab48aff

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

Successfully merging this pull request may close these issues.

None yet

2 participants