                 #stop source
                 @_source.stop()
                 @_elapsedTime = 0
-
-                #create audio nodes
-                gainNode = audioContext.createGain()
-                @_source = audioContext.createBufferSource()
-
-                #set values on source node
-                @_source.buffer = @_buffer
-                @_source.loop = opt.loop ? @_config.loop
-                @_source.onended = =>
-                    @_isEnded = true
-                    @_elapsedTime += audioContext.currentTime - @_startTime
-                    if @_elapsedTime >= @_buffer.duration
-                        @_elapsedTime = 0
-
-                #set value on gain node
-                gainNode.gain.value = opt.volume ? @_config.volume
-
-                #connect nodes
-                @_source.connect gainNode
-                gainNode.connect audioContext.destination
-
-                #record start time
-                @_startTime = audioContext.currentTime
-
-                #start playing
-                @_source.start @_startTime, @_elapsedTime
+                _play.call this, opt
+
     pause: ->
         if Greenhorn.isRunning()
             if @_audio?
                 @_audio.pause()
             else
                 @_source.stop()
+
     stop: ->
         if Greenhorn.isRunning()
             if @_audio?

###

class Sound
    #closure
    _list = []

    #class level objects
    @config:

        if @_audio?
            !(@_audio.paused or @_audio.ended)
        else
            !@_isEnded
    elapsedTime: ->
        if @_audio?
            @_audio.currentTime * 1000
