Re: Continuous playback of javascript synthesized consecutive audio buffers causes audio artifacts when no buffer starving occurs.

Hi Patrick,

Regardless of what the spec says, I can say based on firsthand conversation that the intent of start() was to allow sample-accurate playback, and that the seconds units for a node's starting time are intended to be internally converted to AC sample frame units as a minimum time resolution. The spec needs cleanup, most certainly.

If one schedules playback a "reasonable" amount of time after the current AC time, then the type of interruption you are talking about cannot cause a problem. At some reasonable timer interval, one examines how much audio has been scheduled up to some latest point in AC time units. If the queue of audio to be played in the future is too small, one then schedules more audio nodes after that latest point to "top up" the queue. One has to avoid scheduling something so close to the present AC time that main thread jitter could mess with it. There is obviously a tradeoff between safety/robustness and these latency assumptions.

(And yes it *is* a serious outstanding spec defect that a "reasonable" latency cannot be determined by an application.)


On Oct 30, 2013, at 5:27 PM, Patrick Martin <patrick.martin.r@gmail.com> wrote:

> @Joseph
> Yes, that's true but unfortunately it's not specified how it's sample accurate, playback time is specified in seconds, which are independant of the number of samples, calling  performance.now()*1000 + samples_in_last_buffer/samples_per_second is probably the most reliable way to schedule the audio, but the javascript can get interrupted between calling the time function and scheduling the audio causing cracks pops etc. It's simpler to both implement and use if we either have a way to schedule based on a delay in the format of number of samples played or a way to queue buffers in a AudioBufferQueueNode or similar.
> 
> 
> On Wed, Oct 30, 2013 at 6:29 AM, Joseph Berkovitz <joe@noteflight.com> wrote:
> I don't think the approach of this jsfiddle is kosher for two reasons, which are related.
> 
> 1. Modifying a looped buffer that is playing in the main thread is necessarily going to be subject to jitter, even if there are no races per se.
> 2. Calling start(AC.currentTime) is inherently unreliable because you provide no time for the audio thread to schedule playback in advance.
> 
> And it doesn't produce a clean tone on my machine :)
> 
> @Patrick, if you schedule your buffers a safe amount ahead of the current time, and they are not being up/down sampled, you should get perfectly sample-accurate glitch-free playback in a compliant implementation.
> 
>> 
>> On Tue, Oct 29, 2013 at 2:55 PM, Srikumar K. S. <srikumarks@gmail.com> wrote:
>> Ah I see. 
>> 
>> We've seen some discussion regarding the modifiability of buffers that have 
>> been assigned to source nodes (i.e. the "race condition wars"). This jsfiddle
>> (http://jsfiddle.net/gy5AU/) shows code that modifies a single 22050Hz
>> buffer periodically to generate a glitch-free (up to setTimeout's jitter) 
>> 440Hz sine tone.
>> 
>> This produces a clean tone on my machine unlike the original beep.html
>> test case ... but should this work at all?
>> 
>> -Kumar
>> 
>> On 30 Oct, 2013, at 1:38 am, Joseph Berkovitz <joe@noteflight.com> wrote:
>> 
>>> If I'm not mistaken I think the original issue here was sequencing audio buffers whose playback rate was not equal to the AC sample rate, and were thus being up- or down-sampled for playback. In this case one gets aliasing problems at the splice point between successive buffers, and the spec is silent about this sort of thing. These aliasing issues do not arise when the playback rate and the AC sample rate are equal.
>>> 
>>> I don't think the buffer queue model below would address this (although it's very useful in its own right).
>>> 
>>> On Oct 29, 2013, at 3:18 PM, Srikumar K. S. <srikumarks@gmail.com> wrote:
>>> 
>>>>> It would allow for pre-synthesized audio playback in a glitch free manner.
>>>>> 
>>>> I'm not sure whether this is to address an implementation bug or a spec shortcoming. The concept of a buffer queue can already be expressed using the AudioBufferSourceNode. Whether it works without glitches in current implementations is likely not a spec shortcoming .. unless it is impossible to create such an implementation, which I don't think is the case.
>>>> 
>>>> For instance, see the buffer_queue model at https://github.com/srikumarks/steller/blob/master/src/models/buffer_queue.js. The example code there asks for a function to be called when the queue runs low, but it can sequence buffers passed to the "enqueue" method. 
>>>> 
>>>> Reproducing the 440Hz sine tone example here -
>>>> 
>>>>    var ac = new AudioContext;
>>>>    var sh = new org.anclab.steller.Scheduler(ac);
>>>>    var q = sh.models.buffer_queue();
>>>>    q.connect(ac.destination);
>>>>    q.on('low', function () {
>>>>        var phase = 0.0, dphase = 2.0 * Math.PI * 440.0 / 44100.0;
>>>>        return function (lowEvent, q) {
>>>>            var audioBuffer = q.createBuffer(1, 1024);
>>>>            var chan = audioBuffer.getChannelData(0);
>>>>            var i;
>>>>            for (i = 0; i < 1024; ++i) {
>>>>                chan[i] = 0.2 * Math.sin(phase);
>>>>                phase += dphase;
>>>>            }
>>>>            q.enqueue(audioBuffer);
>>>>        };
>>>>    }());
>>>>    q.start(ac.currentTime);
>>>> 
>>>> -Kumar
>>>> 
>>>> On 30 Oct, 2013, at 12:25 am, Patrick Martin <patrick.martin.r@gmail.com> wrote:
>>>> 
>>>>> It would allow for pre-synthesized audio playback in a glitch free manner.
>>>>> 
>>>>> On Oct 20, 2013 10:06 PM, "Robert O'Callahan" <robert@ocallahan.org> wrote:
>>>>> On Mon, Oct 21, 2013 at 6:35 AM, Srikumar Karaikudi Subramanian <srikumarks@gmail.com> wrote:
>>>>> What advantage might such an AudioBufferSequenceNode have over a ScriptProcessorNode with a queue processing render function?
>>>>> 
>>>>> It would probably have the advantage of not being susceptible to small amounts of main-thread jank.
>>>>> 
>>>>> Rob
>>>>> -- 
>>>>> Jtehsauts  tshaei dS,o n" Wohfy  Mdaon  yhoaus  eanuttehrotraiitny  eovni le atrhtohu gthot sf oirng iyvoeu rs ihnesa.r"t sS?o  Whhei csha iids  teoa stiheer :p atroa lsyazye,d  'mYaonu,r  "sGients  uapr,e  tfaokreg iyvoeunr, 'm aotr  atnod  sgaoy ,h o'mGee.t"  uTph eann dt hwea lmka'n?  gBoutt  uIp  waanndt  wyeonut  thoo mken.o w  
>>>> 
>>> 
>>> .            .       .    .  . ...Joe
>>> 
>>> Joe Berkovitz
>>> President
>>> 
>>> Noteflight LLC
>>> Boston, Mass.
>>> phone: +1 978 314 6271
>>> www.noteflight.com
>>> "Your music, everywhere"
>>> 
>> 
>> 
>> 
> 
> .            .       .    .  . ...Joe
> 
> Joe Berkovitz
> President
> 
> Noteflight LLC
> Boston, Mass. phone: +1 978 314 6271
> www.noteflight.com
> "Your music, everywhere"
> 
> 

.            .       .    .  . ...Joe

Joe Berkovitz
President

Noteflight LLC
Boston, Mass.
phone: +1 978 314 6271
www.noteflight.com
"Your music, everywhere"

Received on Wednesday, 30 October 2013 23:15:09 UTC