Изменение реверберации среды 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 как дочерний узел и добавить его на сцену.

Если вы уже сделали это, но все еще сталкиваетесь с проблемами, обновите ваш фрагмент выше.

Другие вопросы по тегам