ARKit – 空间音频几乎不会随距离变化音量



我创建了一个SCNNode并为其添加了音频。

这是一个单声道音频。一切都设置正确。

它正在作为空间音频工作,这不是问题。

问题是,当我靠近或远离时,它几乎没有改变音量。我知道如果我离得很远,它会改变,但这完全不像苹果在这里展示的那样:

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

我看到其他一些游戏的音量确实从一步距离开始变化。

有了我的,一步你甚至无法分辨出音量的变化。您至少需要 4 个步骤。

有人知道为什么吗?

代码波纹管:

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];

也许节点的规模?

整个场景的大小约为4英尺。

当我添加一个对象时,我通常会将其缩放到 0.005(否则它会变得太大(。 但我也尝试使用一个已经具有 .scn 文件中合适大小的文件中。

它应该不会影响任何事情,因为结果是一个咖啡桌大小的场景,我可以很好地看到物体。

已更新

以下是控制声音衰减的工作代码(适用于iOS和macOS(:

import AVFoundation
import ARKit
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
mySource.load()

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)

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) 
}
}

而且,是的,你是绝对正确的 - 有一些强制性设置。

但是其中有 7个:

  • 使用AVAudioMixing协议及其存根(属性和方法(。

  • 使用MONO音频文件。

  • 使用source.isPositional = true.

  • 使用source.shouldStream = false.

  • maximumDistance值分配给distanceAttenuationParameters属性。

  • referenceDistance值分配给distanceAttenuationParameters属性。

  • mySource.load()的位置在您的代码中非常重要。

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)

如果你用Objective-C编写它,它肯定会起作用

在此示例中,audioNode的距离与listener的距离为 1 米。

如果上述答案似乎都不起作用,请尝试以下代码:

sceneView.audioEnvironmentNode.reverbParameters.enable = true

如果即使这些似乎也几乎不起作用,或者如果您想获得最佳性能,那么有一个名为level的属性,您可以在其中设置代码的空间级别。

sceneView.audioEnvironmentNode.reverbParameters.level = 40

(混响参数的电平范围在 -40 到 40 个参数之间(

最新更新