Изменение реверберации среды SceneKit в Swift?
Я пытаюсь получить 3D аудио эффекты с помощью SceneKit в Swift.
Мой scene.rootNode - это геометрия блока с размером 100x100x100. Внутри scene.rootNode у меня есть boxNode размером 50x5050. Затем внутри boxNode у меня есть audioNode, генерирующий звук размером 1x1x1, а также cameraNode с размером 1x1x1. Позиция audioNode равна 0,0,0, а позиция cameraNode равна 0,0, -10.
Чтобы глубже ощутить пространственное восприятие, я бы хотел добавить реверберацию. Тем не менее, я не могу получить доступ к SCNView.AVAudioEnvironmentNode.
Он компилируется, но среда приводит к нулю и падению.
let environment = sceneView.audioEnvironmentNode
environment.reverbBlend = 0.5 // CRASH!: LLBD
environment.renderingAlgorithm = .HRTFHQ
let reverb = environment.reverbParameters
reverb.enable = true
reverb.loadFactoryReverbPreset(.mediumRoom)
Я также попытался создать свой собственный AVAudioEnvironment, включив реверберацию, а затем присвоив сцену sceneView.audioEnvironmentNode, но XCode говорит, что sceneView.audioEnvironmentNode является неизменным.
Я был бы признателен, если бы кто-нибудь мог помочь мне поставить реверберацию на моей сцене.
Вот мой тестовый код. Спасибо!
import Cocoa
import AVFoundation
import SceneKit
class ViewController: NSViewController {
@IBOutlet weak var sceneView: SCNView!
override func viewDidLoad() {
super.viewDidLoad()
let path = Bundle.main.path(forResource: "Sounds/Test_mono.mp3", ofType: nil)
let url = URL(fileURLWithPath: path!)
let source = SCNAudioSource(url: url)!
source.loops = true
source.shouldStream = false
source.isPositional = true
source.load()
let player = SCNAudioPlayer(source: source)
if let apn = player.audioNode as? AVAudioPlayerNode {
apn.renderingAlgorithm = .HRTFHQ
apn.reverbBlend = 0.5
}
let audioNode = SCNNode(geometry: SCNBox(width:1, height:1, length:1, chamferRadius: 0.1))
let cameraNode = SCNNode(geometry: SCNBox(width:1, height:1, length:1, chamferRadius: 0.1))
cameraNode.camera = SCNCamera()
let boxNode = SCNNode(geometry: SCNBox(width:50, height:50, length:50, chamferRadius: 1))
boxNode.addChildNode(audioNode)
audioNode.position = SCNVector3(x: 0, y: 0, z: 0)
boxNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 0, z: -10)
let scene = SCNScene()
scene.rootNode.geometry = SCNBox(width:100, height:100, length:100, chamferRadius: 0.1)
scene.rootNode.addChildNode(boxNode)
boxNode.position = SCNVector3(x: 0, y: 0, z: 0)
sceneView.scene = scene
sceneView.pointOfView = cameraNode
sceneView.audioListener = cameraNode
let environment = sceneView.audioEnvironmentNode
environment.reverbBlend = 0.5 // CRASH!: LLBD
environment.renderingAlgorithm = .HRTF
let reverb = environment.reverbParameters
reverb.enable = true
reverb.loadFactoryReverbPreset(.mediumRoom)
audioNode.addAudioPlayer(player)
let move = SCNAction.moveBy(x:0, y:1, z:0, duration: 1)
let sequence = SCNAction.sequence([move])
let loop = SCNAction.repeatForever(sequence)
audioNode.runAction(loop)
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
1 ответ
Глядя на первый фрагмент, вы не можете писать только для чтения. audioEnvironmentNode
это свойство только для чтения, которое используется для пространственного SCNPlayer
это было добавлено к сцене.
Просматривая второй (более длинный) фрагмент, вы создаете два узла и применяете реверберацию, но эти узлы никогда не добавляются в сцену.
Согласно Apple Docs для SCNPlayer
Объект SCNAudioPlayer управляет воспроизведением позиционного аудиоисточника в сцене SceneKit. Чтобы использовать позиционное аудио, сначала создайте повторно используемый объект SCNAudioSource или AVAudioNode для предоставления аудиопотока. Затем создайте аудиоплеер для управления воспроизведением этого источника звука. Наконец, подключите аудиопроигрыватель к объекту SCNNode для пространственного воспроизведения трехмерного звука на основе положения этого узла относительно узла audioListener сцены.
Если вы посмотрите на свой код, даже если вы создали player : SCNPlayer
и добавить реверберацию через кастинг apn = player.audioNode as? AVAudioPlayerNode
ни в одной точке вашего кода вы не присоединяете ни один из узлов к узлу SCNNode, находящемуся в сцене.
Я бы порекомендовал вам добавить apn
как дочерний узел и добавить его на сцену.
Если вы уже сделали это, но все еще сталкиваетесь с проблемами, обновите ваш фрагмент выше.