Would someone provide some guidance on utilizing the AVAudioEnvironmentNode.

I would like to use AVAudioEngine for a 3D audio effect, where the sound source 
circles the user head.

In my code, the sound source appears to move from left to right but I've been 
unable to figure out how to make it circle the users head.

I tried HRTF and spherical head algorithm without any noticeable effect.



Do I need AVAudioMake3DVectorOrientation and AVAudioMake3DAngularOrientation 
(two concepts I don't understand) configured in a certain way to make this work?

An odd thing - when the timer is invalidated, the audio stops but shouldn't it 
continue because of the loops option?



_player.scheduleBuffer(audioBuffer!, at: nil, options: .loops, 
completionHandler: nil)



Have I set this up incorrectly or am I experiencing a limitation of spatialized 
audio?



Thank you,





W.





Note: the audio source must be mono because it is a requirement for 
AVAudioEnvironmentNode spatial effect.

Sorry about the formatting.  I couldn't get the indentation corrected





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: "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()

    }

}



}



let audioClass = ThreeDAudio()

audioClass.startAudioTest()
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to