<div dir="ltr"><div dir="ltr"><div dir="ltr"><p class="MsoNormal">RECOMMENDATIONS</p><p class="MsoNormal">1. Convolver: change MFFloat buffer to SFNode buffer
[AudioBuffer]<span></span></p>

<p class="MsoNormal">2. Add AudioBuffer node type<span></span></p>

<p class="MsoNormal">3. Refactor BufferAudioSource to delegate loading to
AudioBuffer<span></span></p>

<p class="MsoNormal">4. browser developers: beware implementing BufferAudioSource
via web audio AudioBufferSource<span></span></p>

<p class="MsoNormal"><span> -Doug Sanden</span></p><p class="MsoNormal"><span><br></span></p>

<p class="MsoNormal">Explanation:<span></span></p>

<p class="MsoNormal">Convolver is incomplete because it doesn't have a field to
specifiy the number of channels in the buffer. Without that, there's no way to
know how many channel chunks to split the MFFloat PCM32 data into. Yet the
documentation claims it can have any number of channels.<span></span></p>

<p class="MsoNormal">3 options to fix:<span></span></p>

<p class="MsoNormal">a) in text, say single channel only<span></span></p>

<p class="MsoNormal">b) add a bufferChannels field<span></span></p>

<p class="MsoNormal">c) delegate loading to AudIoBuffer node<span></span></p>

<p class="MsoNormal">I recommend c) to gain the additional benefits of URL
loading. Most web audio Convolver examples load impulse response data from .wav
files.<span></span></p>

<p class="MsoNormal"><a href="https://middleearmedia.com/web-audio-api-convolver-node/">https://middleearmedia.com/web-audio-api-convolver-node/</a>
<span></span></p>

<p class="MsoNormal">In web audio, both Convolver and AudioBufferSource have a
.buffer field that takes an AudioBuffer node. <span></span></p>

<p class="MsoNormal"><a href="https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode">https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode</a>
<span></span></p>

<p class="MsoNormal">- example code shows loading AudioBuffer from .wav<span></span></p>

<p class="MsoNormal"><a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode">https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode</a>
<span></span></p>

<p class="MsoNormal">- example code shows loading PCM data in AudioBuffer
algorithmically at run time<span></span></p>

<p class="MsoNormal"><a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer">https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer</a>
<span></span></p>

<p class="MsoNormal">- explains 2 ways to load data, from .wav or from raw data
(PCM)<span></span></p>

<p class="MsoNormal"><span> </span></p>

<p class="MsoNormal">Having both BufferAudioSource and Convolver delegate loading
to AudioBuffer will reduce code needed, match web audio, while fixing Convolver
shortcoming and adding url loading to Convolver through AudioBuffer<span></span></p>

<p class="MsoNormal">i have the recommendations working in freewrl with these
scene files:<span></span></p>

<p class="MsoNormal"><a href="https://freewrl.sourceforge.io/tests/16_Sound/convolver_control.wrl">https://freewrl.sourceforge.io/tests/16_Sound/convolver_control.wrl</a>
 <span></span></p>

<p class="MsoNormal"><a href="https://freewrl.sourceforge.io/tests/16_Sound/convolver_control_PCM.wrl">https://freewrl.sourceforge.io/tests/16_Sound/convolver_control_PCM.wrl</a>
 <span></span></p>

<p class="MsoNormal"><a href="https://freewrl.sourceforge.io/tests/16_Sound/BufferAudioSource.x3d">https://freewrl.sourceforge.io/tests/16_Sound/BufferAudioSource.x3d</a>
<span></span></p>

<p class="MsoNormal"><span> </span></p>

<p class="MsoNormal">Implementing BufferAudioSource<span></span></p>

<p class="MsoNormal"><a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode">https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode</a>
<span></span></p>

<p class="MsoNormal">"It will automatically be garbage-collected"
sometime after it quits playing.<span></span></p>

<p class="MsoNormal">The unusual nature of automatic garbage collection in
procedural code doesn't apply well to declarative web3d syntax where nodes
perisist for the life of the scene run. Labsound native library for web audio
has no AudioBufferSourceNode - the one node its missing - due to the garbage
collection behavior, and they've had no requests for it. So I can't test
implementing BufferAudioSource via web audio AudioBufferSource and can't recommend
either way.<span></span></p>

<p class="MsoNormal">In native code via Labsound I'm able to implement
BufferAudioSource the same way as AudioClip --Labsound SampledAudioSource which
has detune and playbackRate, stop,start,loop-- and have that working in
FreeWRL.<span></span></p><p class="MsoNormal"><br></p><p class="MsoNormal">ORIGINAL BUFFERAUDIOSOURCE<span></span></p><p class="MsoNormal"><span style="font-family:Consolas">BufferAudioSource :
X3DSoundSourceNode, X3DUrlObject {<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] autoRefresh          
0.0        [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] autoRefreshTimeLimit 
3600.0     [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  MFFloat 
[in,out] buffer               
[]         [−1,1]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] bufferDuration        0         
[0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] channelCountMode      "max"      ["max",
"clamped-max", "explicit"]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] channelInterpretation
"speakers" ["speakers", "discrete"]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] description           ""  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] detune               
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[in,out] enabled              
TRUE<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] gain                 
1          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[in,out] load                 
TRUE  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[in,out] loop                 
FALSE  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] loopEnd              
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] loopStart            
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFNode  
[in,out] metadata             
NULL       [X3DMetadataObject]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFInt32 
[in,out] numberOfChannels     
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] pauseTime            
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] playbackRate         
1          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] resumeTime           
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] sampleRate           
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] startTime            
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] stopTime             
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  MFString [in,out] url                   []         [URI]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFInt32 
[out]    bufferLength          0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFInt32 
[out]    channelCount                     [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[out]    elapsedTime<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[out]    isActive<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[out]    isPaused<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">}<span></span></span></p><p class="MsoNormal">/ORIGINAL BUFFERAUDIOSOURCE<span></span></p><p class="MsoNormal">REFACTORED BUFFERAUDIOSOURCE<span></span></p><p class="MsoNormal"><span style="font-family:Consolas">AudioBufferSource :
X3DSoundSourceNode {<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFNode   [in,out] buffer                NULL       [AudioBuffer]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] channelCountMode      "max"      ["max",
"clamped-max", "explicit"]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] channelInterpretation
"speakers" ["speakers", "discrete"]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] description           ""  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] detune               
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[in,out] enabled              
TRUE<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[in,out] loop                 
FALSE  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] loopEnd              
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] loopStart             0         
[0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFNode  
[in,out] metadata             
NULL       [X3DMetadataObject]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] pauseTime            
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] playbackRate         
1          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] resumeTime           
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] startTime            
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] stopTime             
0          (-∞,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[out]    elapsedTime<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[out]    isActive<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[out]    isPaused<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">}<span></span></span></p><p class="MsoNormal">/REFACTORED BUFFERAUDIOSOURCE<span></span></p><p class="MsoNormal">AUDIOBUFFER<span></span></p><p class="MsoNormal"><span style="font-family:Consolas">BufferAudioSource :
X3DUrlObject {<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] autoRefresh          
0.0        [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFTime  
[in,out] autoRefreshTimeLimit 
3600.0     [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  MFFloat 
[in,out] bufferData           
[]         [−1,1]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFInt32 
[in,out] bufferChannels       
1          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] channelCountMode      "max"      ["max",
"clamped-max", "explicit"]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] channelInterpretation
"speakers" ["speakers", "discrete"]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFString [in,out] description           ""  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFBool  
[in,out] load                  TRUE  <span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFNode  
[in,out] metadata             
NULL       [X3DMetadataObject]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFFloat 
[in,out] sampleRate           
0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  MFString [in,out] url                   []         [URI]<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFInt32 
[out]    bufferLength          0          [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">  SFInt32 
[out]    channelCount                     [0,∞)<span></span></span></p><p class="MsoNormal"><span style="font-family:Consolas">}<span></span></span></p><p class="MsoNormal"><span> </span></p><p class="MsoNormal">Note on field names bufferData and bufferChannels<span></span></p><p class="MsoNormal">- web audio uses numberOfChannels as does current
BufferAudioNode<span></span></p><p class="MsoNormal">- but its not clear numberOfChannels only applies the the
raw PCM32 data -- not to the URL loaded .wav file which will get its channel
count from the .wav file.<span></span></p><p class="MsoNormal">- to make the association clearer I recommend the names for
buffer data and channel count have the same prefix, so will be sequential in
specs alphabetically listed fields <span></span></p><p class="MsoNormal">





















































































































































</p><p class="MsoNormal">/AUDIOBUFFER<span></span></p><p class="MsoNormal"><br></p></div></div></div>