我想将AVAudioEngine用于3D音频效果,声源环绕用户头部。来源似乎从左向右移动,但我一直无法弄清楚如何让它围绕用户头。音频源必须是单声道或无法正常工作。
我不懂AVAudioMake3DVectorOrientation和AVAudioMake3DAngularOrientation。
我认为我的数学是正确的,但我怀疑如果是,我会得到我想要的结果。
这是骨干,所以没有多少错误检查。
有人会提供指导让我走上正轨吗?
谢谢,
W上。
import AVFoundation
class ThreeDAudio {
var _angleIndx = 0.0
var _engine : AVAudioEngine!
var _player : AVAudioPlayerNode!
var _environment : AVAudioEnvironmentNode!
var _circleTimer : Timer!
func initTimer()
{
_circleTimer = Timer.scheduledTimer(timeInterval: 0.10, target: self,
selector: #selector(ThreeDAudio.updatePosition),userInfo: nil, repeats: true)
}
@objc func updatePosition()
{
let centerX = 0.0
let centerY = 0.0
let radius = 10.0
let degToRads = Double.pi / 180.0
let angle = _angleIndx * degToRads
let x = centerX + sin(angle) * radius
let y = centerY + cos(angle) * radius
let z = 0.0
let posInSpace = AVAudioMake3DPoint(Float(x), Float(y), Float(z))
_angleIndx += 1.0
_player.position = posInSpace
print("angle: \(_angleIndx) , \(posInSpace)")
if(_angleIndx == 360.0) { _circleTimer.invalidate() }
}
func getBufferFromFileInBundle(fileName: String, fileType: String) -> AVAudioPCMBuffer?
{
// audio MUST be a monoaural source or it cant work in 3D
var file:AVAudioFile
var audioBuffer : AVAudioPCMBuffer? = nil
let path = Bundle.main.path(forResource: fileName, ofType: fileType)!
do{
file = try AVAudioFile(forReading: URL(fileURLWithPath:path))
audioBuffer = AVAudioPCMBuffer(pcmFormat:(file.processingFormat), frameCapacity: AVAudioFrameCount(file.length))
try file.read(into: audioBuffer!)
} catch let error as NSError {
print("Error AVAudioFile:\(error)")
}
return audioBuffer
}
func outputFormat() -> AVAudioFormat
{
let outputFormat = _engine.outputNode.outputFormat(forBus: 0)
let nChannels = outputFormat.channelCount // testing, will always be 2 channels
let sampleRate = outputFormat.sampleRate
return AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: nChannels)
}
func setupEngine(_ audioBuffer: AVAudioPCMBuffer )
{
_engine = AVAudioEngine()
_player = AVAudioPlayerNode()
_environment = AVAudioEnvironmentNode()
_player.renderingAlgorithm = .HRTF
_engine.attach(_player)
_engine.attach(_environment)
_engine.connect(_player, to: _environment, format: audioBuffer.format)
_engine.connect(_environment, to: _engine.outputNode, format: outputFormat())
_environment.listenerPosition = AVAudioMake3DPoint(0.0, 0.0, 0.0);
_environment.listenerVectorOrientation = AVAudioMake3DVectorOrientation(AVAudioMake3DVector(0, 0, -1), AVAudioMake3DVector(0, 0, 0))
_environment.listenerAngularOrientation = AVAudioMake3DAngularOrientation(0.0,0.0, 0.0)
do{
try _engine.start()
} catch let error as NSError {
print("Error start:\(error)")
}
}
func startAudioTest()
{
var thisFile = (name: "", fileType: "")
thisFile = (name: "sound_voices", fileType: "wav")
thisFile = (name: "Bouncing-Ball-MONO", fileType: "aiff")
let audioBuffer = getBufferFromFileInBundle(fileName: thisFile.name, fileType: thisFile.fileType )
if ( audioBuffer != nil )
{
setupEngine( audioBuffer! )
initTimer()
_player.scheduleBuffer(audioBuffer!, at: nil, options: .loops, completionHandler: nil)
_player.play()
}
}
}