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

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

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -