ARKit – Spatial Audio barely changes the volume over distance

大城市里の小女人 提交于 2021-02-08 07:17:38

问题


I created a SCNNode and added an Audio to it.

It is a Mono audio. Everything is set up correctly.

It is working as Spatial Audio, that's not the problem.

The problem is that as i get closer or far away it barely changes the volume. I know it changes if i get very very far away, but it's nothing like Apple demonstrated here:

https://youtu.be/d9kb1LfNNU4?t=23

Some other games i see the audio volume really changing from one step distance.

With mine, with one step you can't even tell the volume changed. You need at least 4 steps.

Anyone has any clue why?

Code bellow:

SCNNode *audioNode = [[SCNNode alloc] init];
SCNAudioSource *audioSource = [[SCNAudioSource alloc] initWithFileNamed:audioFileName];
audioSource.loops = YES;
[audioSource load];
audioSource.volume = 0.05; // <-- i used different values. won't change much either
audioSource.positional = YES;
//audioSource.shouldStream = NO; // <-- makes no difference
[audioNode addAudioPlayer:[SCNAudioPlayer audioPlayerWithSource:audioSource]];

[audioNode runAction:[SCNAction playAudioSource:audioSource waitForCompletion:NO] completionHandler:nil];
[massNode addChildNode:audioNode];

Maybe scale of the nodes?

The whole scene is the size of around 4 feet.

When i add an object i usually scale it to 0.005 (otherwise it gets way too big). But i also tried with one that was already in the right size from .scn file.

It shouldn't affect anything tho, since the result is a coffee table size scene and i can see the objects alright.


回答1:


Updated.

Here's a working code for controlling sound's decay (works in iOS and macOS):

import AVFoundation
import SceneKit
import ARKit

@available(iOS 13.0, *)
class ViewController: UIViewController, AVAudioMixing {

    @IBOutlet var sceneView: SCNView!
    // @IBOutlet var sceneView: ARSCNView!

    func destination(forMixer mixer: AVAudioNode,
                                bus: AVAudioNodeBus) -> AVAudioMixingDestination? {
        return nil
    }
    var volume: Float = 0.0
    var pan: Float = 0.0

    var sourceMode: AVAudio3DMixingSourceMode = .bypass
    var pointSourceInHeadMode: AVAudio3DMixingPointSourceInHeadMode = .bypass

    var renderingAlgorithm = AVAudio3DMixingRenderingAlgorithm.sphericalHead
    var rate: Float = 1.2
    var reverbBlend: Float = 40.0
    var obstruction: Float = -100.0
    var occlusion: Float = -100.0
    var position = AVAudio3DPoint(x: 0, y: 0, z: 10)
    let audioNode = SCNNode()

    override func viewDidLoad() {
        super.viewDidLoad()
        let myScene = SCNScene()
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(0, 0, 0)
        myScene.rootNode.addChildNode(cameraNode)

        // let sceneView = view as! SCNView
        sceneView.scene = myScene
        sceneView.backgroundColor = UIColor.orange

        let myPath = Bundle.main.path(forResource: "Mono_Audio", ofType: "mp3")           
        let myURL = URL(fileURLWithPath: myPath!)
        let mySource = SCNAudioSource(url: myURL)!
        mySource.loops = true
        mySource.isPositional = true           // Positional Audio
        mySource.shouldStream = false          // FALSE for Positional Audio
        mySource.volume = volume
        mySource.reverbBlend = reverbBlend
        mySource.rate = rate

        let player = SCNAudioPlayer(source: mySource)
        let sphere: SCNGeometry = SCNSphere(radius: 0.1)
        let sphereNode = SCNNode(geometry: sphere)
        sphereNode.addChildNode(audioNode)
        myScene.rootNode.addChildNode(sphereNode)
        audioNode.addAudioPlayer(player)            

        sceneView.audioEnvironmentNode.distanceAttenuationParameters.maximumDistance = 2
        sceneView.audioEnvironmentNode.distanceAttenuationParameters.referenceDistance = 0.1   
        sceneView.audioEnvironmentNode.renderingAlgorithm = .auto

        // sceneView.audioEnvironmentNode.reverbParameters.enable = true
        // sceneView.audioEnvironmentNode.reverbParameters.loadFactoryReverbPreset(.plate)

        mySource.load()

        let hither = SCNAction.moveBy(x: 0, y: 0, z: 1, duration: 2)
        let thither = SCNAction.moveBy(x: 0, y: 0, z: -1, duration: 2)

        let sequence = SCNAction.sequence([hither, thither])
        let loop = SCNAction.repeatForever(sequence)
        sphereNode.runAction(loop) 
    }
}

And, yes, you're absolutely right – there are some obligatory settings.

But there are 7 of them:

  • use AVAudioMixing protocol with its stubs (properties and methods).

  • use MONO audio file.

  • use source.isPositional = true.

  • use source.shouldStream = false.

  • assign maximumDistance value to distanceAttenuationParameters property.

  • assign referenceDistance value to distanceAttenuationParameters property.

  • and location of mySource.load() is very important in your code.

P.S. If the aforementioned tips didn't help you, then use additional instance properties to make your sound even quieter using a graph, obstacles and orientation of implicit listener:

var rolloffFactor: Float { get set }      // attenuation's graph, default = 1 

var obstruction: Float { get set }        // default = 0.0

var occlusion: Float { get set }          // default = 0.0

var listenerAngularOrientation: AVAudio3DAngularOrientation { get set } // (0, 0, 0)

It definitely works if you'll write it in Objective-C.

In this example the distance of audioNode is 1 meter away from a listener.




回答2:


If none of the above answers seem to work, try the following code:

sceneView.audioEnvironmentNode.reverbParameters.enable = true

And if even these seem to barely work, or if you wanna optimal performance, there is a property called level where you can set the level of how spatial the code can be.

sceneView.audioEnvironmentNode.reverbParameters.level = 40

(the level of the reverbParameters ranges between -40 to 40 parameters)



来源:https://stackoverflow.com/questions/58044242/arkit-spatial-audio-barely-changes-the-volume-over-distance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!