Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Craft 3D AudioSource - A very basic directional audio playing class.

edited January 20 in Code Sharing Posts: 51

Add this component to an empty entity and call entity:play() in order to unpause the audioSource. If loop is set to true, then it will continuously play the audio. If listener ~= nil then the audioSource will calculate the volume and pan using logarithmic rolloff based on the listener's position.

**Changed the code after @binaryblues found a bug, now the volume and pan are updated while the audioSource is looping

audioSource=class()
function audioSource:init(entity,audio,loop,listener)
    self.entity=entity
    entity.audio=audio or nil
    entity.listener=listener or nil
    entity.paused=true
    entity.volume=1
    entity.pan=0
    entity.pitch=1
    entity.minDist=0
    entity.maxDist=100
    entity.loop=loop or false
    self.entity.play=function(entity)
        self.entity.paused=false
    end
end


function audioSource:update()
    if self.entity.listener~=nil then
        self.entity.dist=self.entity.listener.position:dist(self.entity.position)
        if self.entity.listener.x~=self.entity.x then
            self.entity.distX=self.entity.listener.x-self.entity.x
        else self.entity.distX=0 end
        self.entity.volume=
        1/self.entity.dist
        if self.entity.distX<0 then
            self.entity.pan=-(1*self.entity.distX*self.entity.volume)
        elseif self.entity.distX>0 then
            self.entity.pan=-(1*self.entity.distX*self.entity.volume)
        else self.entity.pan=0
        end
    end
    if self.entity.paused==false and self.entity.listener==nil then
        self.entity.sound=sound(self.entity.audio,
        self.entity.volume,
        self.entity.pitch,
        self.entity.pan,
        self.entity.loop)
        self.entity.paused=true
    end
    if self.entity.paused==false and self.entity.listener~=nil then
        self.entity.sound=sound(self.entity.audio,
        self.entity.volume,
        self.entity.pitch,
        self.entity.pan,
        self.entity.loop)
        self.entity.paused=true
    end
    if self.entity.sound~=nil and not self.entity.sound.paused then
        self.entity.sound.volume=self.entity.volume
        self.entity.sound.pan=self.entity.pan
    end
end
Tagged:

Comments

  • Posts: 298

    Very good!

    I thought about the sound effect. It’s really good. But my update doesn’t seem to be working, my test code below:

    function setup()
        -- Create a new craft scene
        scene = craft.scene()
    
        -- Create a new entity
        e = scene:entity()
        e2= scene:entity()
        e.position = vec3(0,0,0)
        e.rotation = quat.eulerAngles(45,45,0) 
        myCanvas = e:add(canvas,100,200,color(83, 80, 233))
        myAudio = e:add(audioSource,asset.downloaded.A_Hero_s_Quest.Arrow_Shoot_1,true,e2)
        e:play()
    
        parameter.number("x",-100,100,0)
    end
    
    function update(dt)
        -- Update the scene (physics, transforms etc)
        scene:update(dt)
        e2.x = x
    end
    
    -- Called automatically by codea 
    function draw()
        update(DeltaTime)
    
        -- Draw the scene
        scene:draw()    
        -- e:draw(12,23,10,10,color(227, 233, 80),drawRnd)
        e:draw(function() drawRnd(e.w2,e.h2,32,32,color(0,255,0,255))end)
    end
    
    function touched(touch)
        if touch.state == BEGAN then
            print("e2:",e2.position)
            print("e:",e.position)
        end
    end
    
  • Posts: 51

    @binaryblues

    Here's a quick example I made, I can see how that would be confusing!

    function setup()
        -- Create a new craft scene
        scene = craft.scene()
    
        -- Create a new entity
        e=scene:entity()
    
        -- Add the audioSource and set it's listener to the camera
    
    e:add(audioSource,asset.downloaded.A_Hero_s_Quest.Arrow_Shoot_1,false,scene.camera)
    
        --Add a monkey because they're cool
        e:add(craft.renderer,craft.model(asset.builtin.Primitives.Monkey))
    
        -- Move the camera forward and rotate it
        scene.camera.position=vec3(0,0,40)
        scene.camera.eulerAngles=vec3(0,-180,0)
    
        parameter.number("tx",-360,360)
        tx=0
        parameter.number("ty",-360,360)
        ty=0
        parameter.number("tz",-360,360)
        tz=0
        parameter.action("play",function()
            e:play()
        end)
    end
    
    function update(dt)
        scene:update(dt)
        -- move the monkey and hit the play action!
        e.position=vec3(tx,ty,tz)
    end
    
    function draw()
        update(DeltaTime)
    
        -- Draw the scene
        scene:draw()
    end
    
  • Posts: 298

    @arismoko What I mean is that if I manually change the X value of the e2 in the code, I get a pretty amazing sound effect, but when I use the parameter.number to dynamically adjust it, the sound intensity doesn’t seem to change at all, check out my test video:

    https://youtu.be/XxLOatN-fXE

    Here’s the effect of manually modifying the X value in the code, which is pretty obvious:

    https://youtu.be/BBcHw_mxuEE

  • edited January 19 Posts: 51

    I see, I never stopped to check that. So when a loop has begun, it seems like the volume doesn't actually update? I'll have to figure out a different way to loop through the sound in that case. Thank you so much for finding that! @binaryblues

  • Posts: 298

    Thanks for your share! I loved the sound effect and thought it would be cool to use in dungeon games in the future, with players hearing footsteps approaching in the dark

  • edited January 20 Posts: 51

    @binaryblues absolutely! if you manage to find a use for this that would be awesome! I just updated it, it was a lot easier than I thought it would be. Here is a video of it looping and updating. Thanks for the help again!

    https://youtube.com/watch?v=cJP6rPDDMqE

  • Posts: 298

    Thanks for your update! It’s all good. It’s working really well!

Sign In or Register to comment.