gpt4 book ai didi

ios - 希望使用SceneKit改变3D空间音频的速度

转载 作者:行者123 更新时间:2023-11-29 05:25:36 35 4
gpt4 key购买 nike

-希望无论您身在何处,每个人都度过美好的一天/晚上! :)

如果此问题的格式/结构不正确,请提前致歉。这是我的第一篇文章,似乎不是所有的引导模式都可以使用屏幕阅读技术访问。抱歉。

我正在尝试创建一个小的场景工具包3D音频演示。我需要对空间音频进行一些音频处理。

即我需要将Varispeed音频单元(或可以产生类似效果的东西)添加到从连接到SCNNode的SCNAudioPlayer播放的音频中。我只需要减慢或加快音频速度,而无需音高补偿。

在闲暇时间里,我一直在寻找Stack和Web的其余部分,以尝试查找魔术,但是到目前为止,它仍然在暗示着我。 :)

为了清楚起见,我检查了:

How to change audio pitch during playback? (Swift 4)

Attaching AudioUnit effects to SCNAudioSource nodes in SceneKit

-并希望这两个对您有帮助的事情……

AVAudioPlayerNode does not play sound

Changing the volume of an SCNAudioPlayer in real time - Swift

-还有来自Stack和其他论坛(Apple等)的许多其他页面,但似乎没有任何示例直接适用于我的特定用例。

已经有一些很好的答案,但到目前为止,这些答案似乎涉及创建AVAudioEngine的单独实例并手动构建图形。我想做的是使用Scene Kit提供的AVAudioEngine的现有实例,并简单地向其中添加某些节点并添加处理后的音频。 -我不清楚这是否可行。

我可以使标准场景工具包3D位置音频正常工作,还可以使AVAudioPlayerNode与当前实例化的AVAudioEngine连接,并使用Varispeed音频单元对其进行处理。但是,音频不会被空间化。

我认为这是因为(如以下代码所示)我将AVAudioPlayerNode连接到Varispeed单元,然后将其连接到引擎的主混音器节点。但是,我找不到其他有关如何配置AVAudioPlayerNode来完成我所需要的示例。

因此,即使我从AVAudioPlayerNode(正在通过varispeed处理)创建SCNAudioPlayer,然后将该SCNAudioPlayer添加到SCNNode,它仍不会以3D呈现。

音频文件可以正常播放,可以进行处理,但不能进行空间化处理。另外,请注意,该文件为mono文件,这是场景工具包要求的,以便将其以3D形式进行空间化。

我的另一个想法是尝试将Varispeed单元的输出添加到引擎的audioEnvironmentNode而不是引擎的主混音器节点,但这对我也不起作用。当我尝试将Varispeed装置连接到引擎的audioEnvironmentNode时,该应用似乎只是挂起。

对于可能发生的情况,我没有从控制台获得任何反馈,并且该应用程序未引发任何异常。但是,它似乎只是执行到Varispeed节点连接到引擎的audioEnvironmentNode,然后似乎挂起为止。 -这对解决这个问题没有帮助。 :)我尝试验证audioEnvironmentNode是否为nil,但无论哪种方式都没有结果。即控制台绝对不会在audioEnvironmentNode上打印任何内容。 -去搞清楚…

我确实打算进一步追求这一点,但在这一点上需要一些帮助。 :)

我的最后一个想法是看是否可以将AVAudioPlayerNode直接添加到SCNNode,但这似乎是不可能的。

最后,这是下面的代码。再次对任何异常格式表示歉意。

感谢您对此的关注,任何人的帮助或建议都将不胜感激!如果我在这里遗漏了一些非常明显的东西,请保持温柔! :)我敢说关于SceneKit和AVFoundation之间的关系的Apple文档至少对我来说不是 super 直观的……

谢谢,干杯! :)

// Creating an AVAudioPlayerNode with processing via Varispeed
let saucerSoundAudioNode = load(file: "ablue", ofType: "wav")

// Creating an SCNAudioPlayer from the AVAudioPlayerNode
let saucerSoundPlayer = SCNAudioPlayer(avAudioNode: saucerSoundAudioNode)

// Adding the SCNAudioPlayer to an SCNNode
saucerNode.addAudioPlayer(saucerSoundPlayer)

// this function loads audio data and creates an aVAudioPlayerNode
// It then connects that node to an instance of AVAudioUnitVarispeed
// The Varispeed node is then connected to the engine's main mixer node
// The function then returns the AVAudioPlayerNode
func load(file name: String, ofType type: String) -> AVAudioPlayerNode {

let audioPlayer = AVAudioPlayerNode()
audioPlayer.volume = 1.0

let path = Bundle.main.path(forResource: "art.scnassets/"+name, ofType: type)!
let url = NSURL.fileURL(withPath: path)

let file = try? AVAudioFile(forReading: url)

let buffer = AVAudioPCMBuffer(pcmFormat: file!.processingFormat, frameCapacity: AVAudioFrameCount(file!.length))

do {
try file!.read(into: buffer!)
} catch _ {

打印(“文件无法读入缓冲区”)
    }

打印(“文件已被读取”)

让引擎= scnView.audioEngine
让音高= AVAudioUnitVarispeed()

engine.attach(audioPlayer)
engine.attach(音高)
      engine.connect(audioPlayer, to: pitch, format: file?.processingFormat)

engine.connect(间距,到:engine.mainMixerNode,格式:file?.processingFormat)

//用scnView.audioEnvironmentNode替换engine.mainMixerNode似乎导致应用挂起
//控制台未指示任何错误,但执行似乎停止了
    audioPlayer.scheduleBuffer(buffer!, at: nil, options: AVAudioPlayerNodeBufferOptions.loops, completionHandler: nil)

return audioPlayer

}

最佳答案

我已经找到了问题的答案,因此希望将其发布,以防其他人对此有相同/相似的问题。

事实证明,在访问SceneKit实例化的AVAudioEngine实例的audioEnvironmentNode之前,需要将audioListener显式设置为pointOfView。

另外,我需要在将侦听器添加到场景之前(而不是之后)在audioListener上设置摄像机。

但是,根据Apple的文档,如果场景中只有一台摄像机(以我的情况为例),则应该将设置该摄像机的节点自动默认设置为pointOfView,从而默认设置为audioListener。

但是实际上,情况似乎并非如此。 -并且,由于pointOfView似乎与我的相机所关联的节点没有关联,因此似乎无法访问当前的音频环境节点。

因此,我在问题中列出的代码确实有效,但稍有调整。

let engine = scnView.audioEngine
let environmentNode = scnView.audioEnvironmentNode
let pitch = AVAudioUnitVarispeed()

engine.attach(audioPlayer)
engine.attach(environmentNode)
engine.attach(pitch)

engine.connect(audioPlayer, to: pitch, format: file?.processingFormat)
engine.connect(pitch, to: environmentNode, format: file?.processingFormat)
engine.connect(environmentNode, to: engine.mainMixerNode, format: nil)

完成此操作后,就像以前一样,我需要做的就是根据返回的AVAudioPlayerNode创建SCNAudioPlayer并将SCNAudioPlayer与SCNNode关联起来,一切都很好! :)音频基于SCNNode的位置以3D形式呈现,并且可以使用连接的AVAudioUnit的参数轻松进行修改。

因此,希望这对其他人有帮助,并祝您度过一个愉快的一天/周末!

干杯! :)

Mod女孩

关于ios - 希望使用SceneKit改变3D空间音频的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58212188/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com