javascript - Web Audio API: Clicks on volume change with slider -


for application makes 1 able determine ones tinnitus frequency, following scenario occurs:

a user 'mousedown' html5 slider -> oscillator @ frequency started. moving handle user can change volume of note.

here (coffeescript-)code responsible whole audio processing:

# coffescript tuner element # enables playing notes via web audio api  class @tuner   constructor: () ->     @playing = false     @whobbling = false     @stopping = false     @atvolumechange = false     @atfadein = false     @activebtn = undefined      if typeof audiocontext isnt "undefined"       @audioctx ?= new audiocontext()     else if typeof webkitaudiocontext isnt "undefined"       @audioctx = new webkitaudiocontext()     else       console.log "browser hat keine webaudioapi"      # make sure listener set correct:     listener = @audioctx.listener     listener.setorientation(0,0,-1,0,1,0)     listener.setposition(0,0,0)      # create pannernode , set l , r     @pannernode = @audioctx.createpanner()     @pannernode.setorientation(0,0,0)     @pannernode.setposition(0,0,1)     @pannernode.connect( @audioctx.destination )      # create gainnode , set 0.0     @gainnode = @audioctx.creategain()     @gainnode.gain.value = 0.0     @gainnode.connect @pannernode     @actualfreq = 500     @currentvolume = 0.0    start: (volume, elem_id) ->     if @playing or @stopping       return      @playing = true     @currentvolume = volume     @oscillator = @audioctx.createoscillator()     @oscillator.type = "sine"     @oscillator.frequency.value = @actualfreq     @oscillator.connect @gainnode      # if whobbling active, create lfo & lfogain effect     if @whobbling       lfo = @audioctx.createoscillator()       lfo.type = "sine"       lfo.frequency.value = 5        whobgain = @actualfreq * 5.0 / 100.0       lfo_gain = @audioctx.creategain()       lfo_gain.gain.value = whobgain        lfo.connect(lfo_gain)       lfo_gain.connect(@oscillator.frequency)       lfo.start(0)      # starting process     @activebtn = elem_id     matchinggui.highlightplay( @activebtn ) if @activebtn     = @audioctx.currenttime     @atfadein = true     @gainnode.gain.setvalueattime 0.0, + 0.01     @oscillator.start(now + 0.02)     @gainnode.gain.setvalueattime 0.0, + 0.03     @gainnode.gain.linearramptovalueattime volume, + 0.2     = @     settimeout ->       that.atfadein = false     , 200    stop: () ->     if @playing , not @stopping       @stopping = true       = @audioctx.currenttime       += 0.3 if @atvolumechange       += 0.3 if @atfadein       @gainnode.gain.setvalueattime @currentvolume, + 0.01       @gainnode.gain.linearramptovalueattime 0.0, + 0.45       @oscillator.stop( + 0.5 )       matchinggui.highlightstop(@activebtn) if @activebtn       = @       settimeout ->         that.stopping = false         that.playing = false         that.whobbling = false       , 750    setfrequency: (newfreq) ->     @actualfreq = newfreq     @oscillator.frequency.value = newfreq if @playing , not @stopping    changevolume: (newvolume) ->     newvolumedb = @lineartodb newvolume     if not @stopping       @atvolumechange = true       = @audioctx.currenttime       @currentvolume = newvolumedb       @gainnode.gain.exponentialramptovalueattime @currentvolume, + 0.333       = @       settimeout ->         that.atvolumechange = false       , 300    setwhobbling: () ->     @whobbling = true    setpantolr: () ->     @pannernode.setposition(0,0,1) unless @playing    setpantol: () ->     @pannernode.setposition(-3,0,0) unless @playing    setpantor: () ->     @pannernode.setposition(3,0,0) unless @playing    play: (frequency, volume,  whob, elem_id) ->     whob ?= false     @setfrequency frequency     @setwhobbling() if whob     volumedb = @lineartodb( volume )     @start( volumedb, elem_id )    lineartodb: (s) ->     dbstart = 90     s = s * dbstart - dbstart     return math.pow 10, s/20  # === end class tuner === # # export tuner root = exports ? window root.tuner = tuner 

tuner.play() connected sliders 'mousedown' callback , tuner.changevolume() sliders 'input' callback.

the problem follows:

every time slider moved, clicking occurs. guess reason every time slider fires 'input', ramp, driven tuner.changevolume method, overlaid ramp.

i experimented lot (no scheduling, cancelscheduledvalues, ...) , version above leaves 1 last clicking when slider moved various browsers on mac. browsers on windows machine clicking increases significantly.

(btw. seems not possible read out @gainnode.gain.value when ramp driven.)

any idea how handle problem? i'd thankful hint...

it may oscillators restarting. not familiar coffeescript (need more coffee...) can't directly root out problem if click , drag sliding event perhaps browser improperly sending multiple mousedowns mousemove event.

instead why not have oscillators running gain node @ 0, no output. when user goes on gain ramps , tracks user input. practice use ramps, if trigger volume change occur mousemove, users not move slidders fast enough 'zipping' effect think want avoid.


Comments

Popular posts from this blog

iis - ASP.Net Core CreatedAtAction in HttpPost action returns 201 but entire request ends with 500 -

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -