Funny question about buffer Size/Preload Size,



  • What's the downside of having (a large) buffer size and preload size set to... let's say 32766? I'm usually running at 4096 and 8192, but when I add two constant mods with +1 octave each, I'm having problems.

    Cheers!



  • Besides the increased memory usage there is none. However I'm not super satisfied with the new handling of the max sampler pitch - under no circumstances it should create a crash, but it's hard to come up with a solution that works for the vast range of use cases.

    The underlying problem is that the streaming engine uses different buffers to hold the data that is fetched by the background thread (the preload buffer that contains the beginning of each sample as well as two streaming buffers per voice).

    Now if a sample is played back much faster than it was recorded, the size of the buffers might not be large enough to hold the sample data required for a single audio block. So for example if the audio buffer size is 512 and the sample is being pitched up by 3 octaves (which results in a pitch ratio of 2^3 = 8), the streaming buffer must hold 4096 samples that will be squished into the 512 sample buffer. As soon as you pitch it up a little bit more, it would need more samples than are available and thus crash the system. In order to prevent this, I introduced a max sampler pitch ratio (that is a constant named MAX_SAMPLER_PITCH) where you can define that threshold. Any pitch ratio above this was be capped to the max value ensuring that the pitch ratio will not lead to a read violation (the streaming buffers take that value into account and automatically resize themselve to always fit the AudioBufferSize * MAX_SAMPLER_PITCH).

    This let's you decide on a per-project basis how high you want the pitch ratio to be before it's capped - but be aware that just bumping the `MAX_SAMPLER_PITCH_RATIO to over 9000 will increase the memory consumption to a point where the memory savings of streaming becomes irrelevant.

    However that leads to the irritating "feature" where the pitch ratio doesn't change for sample maps where you map a few samples over the entire range:

    375820d9-da86-4bcd-b1df-5eb9fb170a3d-image.png

    The red range 3 octaves about the root note (indicated by the very professional arrow) will be played back with the exact same pitch, which is not what you expect.

    So in the next iteration of fixing this problem I added a check for the maximum static repitch factor that is simply the difference between HiKey - RootNote. If this pitch ratio exceeds the MAX_SAMPLER_PITCH value, the entire sample is loaded into memory. The rationale behind this is that this method of mapping samples all over the place will most likely happen with small sample sets that are used in an experimental context (because chances are huge that if you have to repitch a single sample over multiple octaves, this will not be a huge sample set so we can simply deactivate the streaming engine completely without blowing up the memory consumption).

    However the key word here is static - the sampler has no way of detecting dynamic pitch changes which are introduced from "the outside" (either by using modulators or calling Synth.addPitchFade()) and this leaves the door open for crashes that might happen as soon as you "dynamically" raise the pitch factor above the MAX_SAMPLER_PITCH. You can prevent those crashes by manually bumping the buffer sizes like @marcLab suggested, however this should not be the user's concern, but now I'm wondering what the next iteration of solving this problem might be. I have multiple ideas, so maybe we can discuss which is the best way to go forward on this:

    1. Reintroducing the capping of MAX_SAMPLER_PITCH for samples that are not loaded into memory because of their static pitch ratio.
      Advantage: no crashes anymore, sample maps with high static pitch ratios are not capped
      Disadvantage: the capped pitch ratio will appear again with dynamic modulation

    2. Tell the streaming engine what maximum dynamic pitch ratio it can expect (so that it will take this into account on top of the static ratio). This would be something like a Sampler.setMaxDynamicPitchRatio() call

    Maybe I can combine 1 and 2 - so the default behaviour will cap the pitch ratio if it exceeds dynamically, but then you can use the second API call to enable high dynamic pitch ratios if you hit that boundary.



  • @Christoph-Hart said in Funny question about buffer Size/Preload Size,:

    Advantage: no crashes anymore, sample maps with high static pitch ratios are not capped

    Thanks! @Christoph-Hart. That answers my question and clarifies a lot of things.
    I did bring the buffer up and the number of voices down, and it seems like it has fixed the problem, no more crashing for now.

    What would be the disadvantage of having something like Sampler.setMaxDynamicPitchRatio()?


Log in to reply
 

12
Online

1.3k
Users

4.3k
Topics

38.6k
Posts