- From: Chris Wilson <cwilso@google.com>
- Date: Mon, 17 Mar 2014 14:52:48 -0700
- To: Raymond Toy <rtoy@google.com>
- Cc: KeonHo Kim <keonho07.kim@samsung.com>, "public-audio@w3.org" <public-audio@w3.org>
- Message-ID: <CAJK2wqXDBUC2T0GTQ-_W2aTvwo6j=HkOXa9VyrNqg5PNCXkG-g@mail.gmail.com>
I actually think start() should throw if the buffer is null. On Mon, Mar 17, 2014 at 2:50 PM, Raymond Toy <rtoy@google.com> wrote: > I also agree. But note that case 1: > > < case1 > > sourcenode.buffer = null; > sourcenode.start(0); // mute > ... > sourcenode.buffer = meaningfulbuffer; // sound > > I personally feel this should not be allowed either. > > > On Mon, Mar 17, 2014 at 12:02 PM, Chris Wilson <cwilso@google.com> wrote: > >> That would be my suggestion, yes. Others should weigh in, though. >> >> >> On Sun, Mar 16, 2014 at 11:43 PM, KeonHo Kim <keonho07.kim@samsung.com>wrote: >> >>> @Chris Wilson. >>> >>> >>> >>> Thanks for clarification. >>> >>> Can I expect one of future draft will be tried to included more explicit >>> description about this issue.? >>> >>> According to your opinion below 4 cases should throw exception. My >>> understanding is correct ? J >>> >>> >>> >>> < case1 > >>> sourcenode.buffer = null; >>> sourcenode.start(0); >>> ... >>> sourcenode.buffer = meaningfulbuffer; // Exception “It has been tried to >>> set buffer after AudioBufferSourceNode is already started.” >>> >>> >>> >>> < case2 > >>> sourcenode.buffer = meaningfulbuffer; >>> sourcenode.start(0); >>> ... >>> sourcenode.buffer = null; // Exception “It has been tried to set buffer >>> after AudioBufferSourceNode is already started.” >>> ... >>> sourcenode.buffer = meaningfulbuffer; // Exception “It has been tried to >>> set buffer after AudioBufferSourceNode is already started.” >>> >>> >>> >>> < case 3 > >>> sourcenode.start(0); >>> sourcenode.buffer = meaningfulbuffer; // Exception “It has been tried to >>> set buffer after AudioBufferSourceNode is already started.” >>> >>> >>> >>> < case 5 > >>> sourcenode.buffer = meaningfulbuffer1; >>> sourcenode.start(0); // sound buffer1 >>> >>> sourcenode.buffer = meaningfulbuffer2; // Exception “It has been tried >>> to set buffer after AudioBufferSourceNode is already started.” >>> >>> >>> >>> Br, >>> >>> KeonHo >>> >>> *From:* Chris Wilson [mailto:cwilso@google.com] >>> *Sent:* Saturday, March 15, 2014 6:48 AM >>> *To:* KeonHo Kim >>> *Cc:* Raymond Toy; public-audio@w3.org >>> >>> *Subject:* Re: AudioBufferSourceNode.buffer how to work it. >>> >>> >>> >>> "null" refers to the Javascript null object; perhaps we need to be more >>> explicit about that. >>> >>> >>> >>> I have no idea why any implementation would re-start the buffer once >>> it's already playing; personally, I think we should explicitly ignore >>> setting the buffer once it has been set. >>> >>> >>> >>> On Wed, Mar 12, 2014 at 6:51 PM, KeonHo Kim <keonho07.kim@samsung.com> >>> wrote: >>> >>> >>> >>> 2014-03-13 3:01 GMT+09:00 Raymond Toy <rtoy@google.com>: >>> >>> I think I'm confused. The spec says: >>> >>> >>> >>> The number of channels of the output always equals the number of >>> channels of the AudioBuffer assigned to the .buffer attribute, or is one >>> channel of silence if .buffer is NULL. >>> >>> >>> >>> I had interpreted NULL to mean 0. But there's also the Javascript object >>> null. >>> >>> >>> >>> I'm not sure what the spec is saying now, so my comments on your >>> examples maybe be all wrong. >>> >>> >>> >>> Khno> "or is one channel of silence if .buffer is NULL." >>> >>> I believe that is Javascript object null. That was mentioned a nullable >>> buffer in this code reivew. >>> >>> If it is not common word expression "nullable", I sorry make you >>> confused. >>> >>> https://codereview.chromium.org/190953005/ >>> >>> >>> >>> In my investigation, source.buffer =0; returns >>> >>> FF TypeError : "Value being assigned to AudioBufferSourceNode.buffer is >>> not an object" >>> >>> Chrome TypeError : "Failed to set the 'buffer' property on >>> 'AudioBufferSourceNode': The provided value is not of type 'AudioBuffer'." >>> >>> >>> >>> source.buffer = null; returns >>> >>> FF : Fine. >>> >>> Chrome TypeError: "Failed to set the 'buffer' property on >>> 'AudioBufferSourceNode': buffer cannot be null." >>> >>> >>> >>> I would like to fix this one on chrome, setting a nullable buffer. >>> >>> >>> >>> One second thoughts, "there was no "when" which could control accurate >>> timing on setting a buffer at source node that was already started.", >>> >>> I think we should consider about implementation separately between >>> AudioBufferSourceNode and AudioBuffer. >>> >>> The "when" in start() or stop() is specific time >>> for AudioBufferSourceNode, NOT a buffer's start or stop timing. >>> >>> If JS developers want to make two sound stream with different timing, >>> they should have created two AudioBufferSourceNode as you know. >>> >>> But, AudioBufferSourceNode should be able to play any AudioBuffers even >>> if there is changing of AudioBuffer on runtime >>> >>> until finishing to render current AudioBuffers(no loop attributes in >>> sourceNode) or intentional calling stop(). >>> >>> >>> >>> In AudioBufferSourceNode perspective, if there is a current buffer which >>> is not reached duration time, it must be running if there is no calling a >>> stop(0 or AudioContext.currentTime). >>> >>> In addition, if there is stop(AudioContext.currentTime + 20sec), Node >>> must be running until end time. >>> >>> According to https://github.com/WebAudio/web-audio-api/issues/15, the >>> spec has been changed to allow calling a stop() multiple times differently >>> with start(). >>> >>> "Discussion results: last-called stop() should take effect, i.e. an >>> overwrite of the last stop(). Multiple stop() invokes should not throw, >>> even if the playback has already stopped." >>> >>> >>> >>> It means JS developer can make stopping a AudioBufferSourceNode delay >>> with overwrite stop() with new "when". >>> >>> >>> >>> In spec, >>> >>> The stop method >>> >>> Schedules a sound to stop playback at an exact time. >>> >>> The *when* parameter describes at what time (in seconds) the sound >>> should stop playing. It is in the same time coordinate system as >>> AudioContext.currentTime. If 0 is passed in for this value or if the value >>> is less than*currentTime*, then the sound will stop playing immediately >>> >>> >>> >>> So, it mentioned AudioContext.currentTime. The "when" is based >>> on AudioContext.currentTime. It means JS developer should call start or >>> stop with "AudioContext.currentTime + delta". >>> >>> This kind of description supports that "when" is meaningful for >>> AudioBufferSourceNode's life cycle and scheduling, NOT a buffer. >>> >>> >>> >>> I think that FF is working properly below 5 test cases. >>> https://codereview.chromium.org/190953005/, it is giving same behavior >>> to Chrome as FF do except case 5. >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> On Tue, Mar 11, 2014 at 9:42 PM, KeonHo Kim <keonho07.kim@samsung.com >>> > wrote: >>> >>> >>> 2014-03-12 2:31 GMT+09:00 Raymond Toy <rtoy@google.com>: >>> >>> >>> >>> >>> >>> On Tue, Mar 11, 2014 at 2:03 AM, KeonHo Kim <keonho07.kim@samsung.com >>> > wrote: >>> >>> Dear All. >>> >>> >>> >>> If there is setting a buffer of AudioBufferSourceNode, how it should >>> work? >>> >>> I think that AudioBufferSourceNode.buffer should be able to set buffer >>> anytime whatever the node is playing or not. >>> >>> I believe if all cases are able to JS developer, it is fantastic. >>> >>> >>> >>> I think that in all of the cases below, you don't have sample accurate >>> timing. The sound for meaningfulbuffer will start at some uncontrolled time >>> after setting the buffer. I think in all cases you can get the effect you >>> want by just creating a new AudioBufferSourceNode with the appropriate >>> buffer and calling start and stop appropriately. >>> >>> >>> >>> Chris Rogers certainly intended that AudioBufferSourceNodes to be cheap >>> to create and use. >>> >>> >>> >>> Khno> I'm getting clear what he intended from discussion with you. I >>> agree with you. >>> >>> There is no "when" which can control accurate timing. >>> >>> Don't we need to mention "setBuffer() must be called before calling >>> start()" such like this?. >>> >>> I think that will be helpful for developer. >>> >>> >>> >>> >>> >>> < case1 > >>> sourcenode.buffer = null; >>> sourcenode.start(0); // mute >>> ... >>> sourcenode.buffer = meaningfulbuffer; // sound >>> >>> >>> >>> This case is, I think, currently supported, but I find it's behavior odd >>> because the sound will start at some uncontrolled time. >>> >>> >>> >>> Khno> Actually, chrome returns domexception "ailed to set the 'buffer' >>> property on 'AudioBufferSourceNode': buffer cannot be null" on sourcenode.buffer >>> = null; >>> >>> Firefox is not. >>> >>> < case2 > >>> sourcenode.buffer = meaningfulbuffer; >>> sourcenode.start(0); // sound >>> ... >>> sourcenode.buffer = null; // mute >>> ... >>> sourcenode.buffer = meaningfulbuffer; // sound >>> >>> >>> >>> I think this is better done by calling sourcenode.stop() instead of >>> setting the buffer to null. Then create a new new node with >>> meaningfulbuffer. >>> >>> >>> >>> Khno> Yes, it is better approach to keep idea that Chris Rogers intent. >>> >>> < case 3 > >>> sourcenode.start(0); >>> sourcenode.buffer = meaningfulbuffer; // sound >>> >>> >>> >>> I think this is the same as case 1 >>> >>> >>> >>> Khno> Firefox and Chrome work fine both. >>> >>> < case 4 > >>> sourcenode.buffer = meaningfulbuffer; >>> sourcenode.start(0); // sound >>> >>> >>> >>> This is the normal case. >>> >>> >>> >>> Khno> Firefox and Chrome work fine both. >>> >>> < case 5 > >>> sourcenode.buffer = meaningfulbuffer1; >>> sourcenode.start(0); // sound buffer1 >>> >>> … >>> >>> sourcenode.buffer = meaningfulbuffer2; // sound buffer2 >>> >>> >>> >>> I don't know how that is supposed to work, especially since start() is >>> only allowed to be called once for each AudioBufferSourceNode. Even if you >>> allowed more than one call, I still don't know how this is supposed to >>> behave. >>> >>> >>> >>> >>> >>> Khno> Firefox and chrome are different. >>> >>> >>> >>> In FF >>> >>> If there is "sourcenode.buffer = meaningfulbuffer1" then start(0), play meaningfulbuffer1 >>> from begin of buffer. >>> >>> Then, if there is "sourcenode.buffer = meaningfulbuffer2", sound >>> changed to meaningfulbuffer2 from begin of buffer. >>> >>> Then, if there is "sourcenode.buffer = meaningfulbuffer1" again, play meaningfulbuffer1 >>> from middle of buffer when "sourcenode.buffer = meaningfulbuffer2" was >>> called. >>> >>> >>> >>> In Chrome >>> >>> If there is "sourcenode.buffer = meaningfulbuffer1" then start(0), play meaningfulbuffer1 >>> from begin of buffer. >>> >>> Then, if there is "sourcenode.buffer = meaningfulbuffer2", sound >>> changed to meaningfulbuffer2 from begin of buffer. >>> >>> Then, if there is "sourcenode.buffer = meaningfulbuffer1" again, play meaningfulbuffer1 >>> from begin of buffer. >>> >>> >>> >>> If a JS developer can not do setting buffer multiple times or not allow >>> setting buffer after calling start() once, FF and Chrome have wrong >>> behavior both. >>> >>> How do you think this case ? Need to notify "Buffer can not be set more >>> than once" ? >>> >>> >>> >>> >>> >>> -- >>> >>> Ray >>> >>> >>> >>> >>> >>> >>> >>> In spec, nullable buffer is existed which has mono channel silence can >>> help making source muted to AudioBufferSourceNode without stop(). >>> >>> If setting buffer or calling start() is allowed more than once, >>> AudioBufferSourceNode can be reused. >>> >>> >>> >>> Is there any confirmed change about calling start() multiple times? >>> >>> >>> >>> >>> >>> However, it also has some issue. >>> >>> “The spec doesn't say, but the buffer attribute of an >>> AudioBufferSourceNode should probably be only settable once. >>> >>> If you've started the source node and change the buffer while the >>> previous buffer is playing, you have no control over when the new source >>> starts.” >>> >>> https://github.com/WebAudio/web-audio-api/issues/288 >>> >>> >>> >>> Please feel free to give your opinion and correct way for Web Audio API. >>> >>> >>> >>> Br, >>> >>> Khno >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> *From:* Raymond Toy [mailto:rtoy@google.com] >>> *Sent:* Wednesday, March 12, 2014 2:32 AM >>> *To:* KeonHo Kim >>> *Cc:* public-audio@w3.org >>> *Subject:* Re: AudioBufferSourceNode.buffer how to work it. >>> >>> >>> >>> >>> >>> >>> >>> On Tue, Mar 11, 2014 at 2:03 AM, KeonHo Kim <keonho07.kim@samsung.com> >>> wrote: >>> >>> Dear All. >>> >>> >>> >>> If there is setting a buffer of AudioBufferSourceNode, how it should >>> work? >>> >>> I think that AudioBufferSourceNode.buffer should be able to set buffer >>> anytime whatever the node is playing or not. >>> >>> I believe if all cases are able to JS developer, it is fantastic. >>> >>> >>> >>> I think that in all of the cases below, you don't have sample accurate >>> timing. The sound for meaningfulbuffer will start at some uncontrolled time >>> after setting the buffer. I think in all cases you can get the effect you >>> want by just creating a new AudioBufferSourceNode with the appropriate >>> buffer and calling start and stop appropriately. >>> >>> >>> >>> Chris Rogers certainly intended that AudioBufferSourceNodes to be cheap >>> to create and use. >>> >>> >>> >>> < case1 > >>> sourcenode.buffer = null; >>> sourcenode.start(0); // mute >>> ... >>> sourcenode.buffer = meaningfulbuffer; // sound >>> >>> >>> >>> This case is, I think, currently supported, but I find it's behavior odd >>> because the sound will start at some uncontrolled time. >>> >>> < case2 > >>> sourcenode.buffer = meaningfulbuffer; >>> sourcenode.start(0); // sound >>> ... >>> sourcenode.buffer = null; // mute >>> ... >>> sourcenode.buffer = meaningfulbuffer; // sound >>> >>> >>> >>> I think this is better done by calling sourcenode.stop() instead of >>> setting the buffer to null. Then create a new new node with >>> meaningfulbuffer. >>> >>> >>> >>> < case 3 > >>> sourcenode.start(0); >>> sourcenode.buffer = meaningfulbuffer; // sound >>> >>> >>> >>> I think this is the same as case 1 >>> >>> < case 4 > >>> sourcenode.buffer = meaningfulbuffer; >>> sourcenode.start(0); // sound >>> >>> >>> >>> This is the normal case. >>> >>> < case 5 > >>> sourcenode.buffer = meaningfulbuffer1; >>> sourcenode.start(0); // sound buffer1 >>> >>> … >>> >>> sourcenode.buffer = meaningfulbuffer2; >>> >>> sourcenode.start(0); // sound buffer2 >>> >>> >>> >>> I don't know how that is supposed to work, especially since start() is >>> only allowed to be called once for each AudioBufferSourceNode. Even if you >>> allowed more than one call, I still don't know how this is supposed to >>> behave. >>> >>> >>> >>> >>> >>> -- >>> >>> Ray >>> >>> >>> >>> >>> >>> >>> >>> In spec, nullable buffer is existed which has mono channel silence can >>> help making source muted to AudioBufferSourceNode without stop(). >>> >>> If setting buffer or calling start() is allowed more than once, >>> AudioBufferSourceNode can be reused. >>> >>> >>> >>> Is there any confirmed change about calling start() multiple times? >>> >>> >>> >>> >>> >>> However, it also has some issue. >>> >>> “The spec doesn't say, but the buffer attribute of an >>> AudioBufferSourceNode should probably be only settable once. >>> >>> If you've started the source node and change the buffer while the >>> previous buffer is playing, you have no control over when the new source >>> starts.” >>> >>> https://github.com/WebAudio/web-audio-api/issues/288 >>> >>> >>> >>> Please feel free to give your opinion and correct way for Web Audio API. >>> >>> >>> >>> Br, >>> >>> Khno >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >> >> >
Received on Monday, 17 March 2014 21:53:17 UTC