Provide a consistent spatial audio experience across all supported devices with geometry-aware audio.

Posts under PHASE tag

26 Posts

Post

Replies

Boosts

Views

Activity

Feedback on Apple Spatial Audio re-render behavior for Dolby Atmos music delivery — perspective from a working mix engineer
Hey everyone, quick disclaimer before jumping in - I used my LLM to structure this around notes/observations I've been taking the last several months. I apologize for the length but felt this was the best distillation of an important challenge my peers and I are facing in mixing music for the largest device/service segment of the listening community - Airpods Pro/Max via Apple Music. Thanks in advance for reading and any feedback you can offer! -Kyle I'm a professional mix engineer working primarily in contemporary pop, indie, and country. After 20+ years of working in stereo, I've started delivering Dolby Atmos ADM masters for Apple Music distribution. I want to share some specific observations about the Apple Spatial Audio re-render in the hope that it's useful to the team that owns this rendering pipeline — and to ask a few questions I haven't been able to find answered in public documentation. I recognize this sits at an unusual intersection of the developer platform and the Apple Music delivery side of the house, but since the rendering behavior is ultimately a platform-level decision, this felt like the right place to start. Background: the three-format problem When delivering an Atmos ADM master, a mixer effectively has to satisfy three distinct listening contexts simultaneously: Speaker playback (7.1.4 or similar) via the Dolby renderer Dolby binaural re-render (AC-4), as heard on TIDAL and Amazon — which respects the OFF/NEAR/MID/FAR binaural mode settings on beds and objects Apple Spatial Audio headphone re-render on Apple Music The first two have reasonably predictable translation. The third is where I'm running into consistent issues — and where I'd value any guidance Apple is able to share. The core issue: Apple's re-render discards binaural mode metadata As best I can tell from testing and from community documentation, Apple's pipeline ingests the ADM, creates an internal 7.1.4 render, and then applies its own proprietary binaural spatialization — one that does not reference the OFF/NEAR/MID/FAR binaural mode parameters embedded by the mixer. This is distinct from the Dolby AC-4 path, which does honor those settings. In practice, this means: Apple's re-render applies a consistent room character regardless of what the mixer has specified for individual elements Elements like lead vocals and kick/snare — which I'm routing through beds or objects with OFF or NEAR binaural settings specifically to preserve intimacy and punch — receive the same ambient room treatment as wider, more spacious elements The result on Apple Music has noticeably more perceived distance and "room" on transient-heavy and close-mic'd elements than either the speaker mix or the Dolby binaural render To be specific about the perceptual effect: the Apple re-render's virtual room introduces early reflections and a sense of speaker-to-listener distance that significantly undercuts the intimacy and impact of close elements. On a pop or country vocal, this is the difference between a performance that feels present and direct versus one that feels recessed in a listening space. On drums, transient attack is softened in a way that doesn't happen in any other delivery context for the same master. Questions for the team I'd be grateful for any clarity on the following: Is the behavior of ignoring OFF/NEAR/MID/FAR metadata intentional and permanent, or is it something that may change as the rendering pipeline evolves? Is there any mechanism — existing or planned — by which a mixer can influence the room character or "closeness" of elements in Apple's re-render, outside of object positioning metadata? Is there any documentation of how Apple's binaural spatialization layer translates object distance metadata (as opposed to binaural mode) — i.e., does Z-axis positioning in the Atmos object space affect perceived distance in the re-render? Is there a recommended workflow or set of delivery parameters that Apple's audio team considers optimal for music content specifically, as opposed to film/TV? Notes on the Audiomovers Binaural Renderer for Apple Music I'm aware of and have used the Audiomovers plugin, which I understand was developed in collaboration with Apple and accurately reflects the Apple Spatial re-render during session monitoring. It's a genuinely useful tool and has improved my ability to anticipate Apple's output. My questions above are about the underlying rendering behavior — not the monitoring workflow, which is solved. Why this matters for music specifically Film and TV post content has different expectations around spatialization — a consistent room or "cinema" quality to the binaural render is arguably appropriate for that material. For music, particularly in contemporary genres where the stereo mix is already highly produced and intimate, an added room layer competes with the mix's own space design and consistently pushes elements further from the listener than intended. I'd argue music content would benefit from a rendering mode with a more "dry" or near-field room character — and I suspect I'm not alone in this among working Atmos music mixers. I'm happy to provide specific A/B examples or additional technical detail if that's useful to anyone on the platform team. Thanks for reading.
0
1
181
2w
I built apple.PHASE with Unity and targeted with visionOS, but Reverb does not sound.
Environment Versions ・macOS15.6.1 ・visionOS26.0.1 ・Xcode16.1 or 26.0.1 ・unity6000.2.9f1 ・Apple.core3.2.0 ・Apple.PHASE1.2.7 ・polyspatial2.4.2 With the above environment, after installing Apple.PHASE into unity and building to a visionOS device, Audio is available and distance attention works, but Early Reflection and Late Reverb produce no audible change even when checked and their parameters are adjusted. What is required to make Early Reflection and Late Reverb take effect on a visionOS device build? action taken ・created a SoundEvent. ・in composer, created a Sampler and a SpatialMixer; attached an AudioClip to the Sampler; enabled Direct Path, Early Reflection, and Late Reverb on the SpatialMixer. ・attached a PHASE Source to the object to be played, attached the created SoundEvent to it, and set non-zero values for Early Reflection and Late Reverb. ・attached a PHASE Listener to the mainCamera and set the ReverbPreset to a value other than None. ・in project settings > Audio, set Spatializer plugin to PHASE Spatializer. ・from there, build for visionOS.
0
0
913
Nov ’25
Spatial Audio on iOS 18 don't work as inteneded
I’m facing a problem while trying to achieve spatial audio effects in my iOS 18 app. I have tried several approaches to get good 3D audio, but the effect never felt good enough or it didn’t work at all. Also what mostly troubles me is I noticed that AirPods I have doesn’t recognize my app as one having spatial audio (in audio settings it shows "Spatial Audio Not Playing"). So i guess my app doesn't use spatial audio potential. First approach uses AVAudioEnviromentNode with AVAudioEngine. Chaining position of player as well as changing listener’s doesn’t seem to change anything in how audio plays. Here's simple how i initialize AVAudioEngine import Foundation import AVFoundation class AudioManager: ObservableObject { // important class variables var audioEngine: AVAudioEngine! var environmentNode: AVAudioEnvironmentNode! var playerNode: AVAudioPlayerNode! var audioFile: AVAudioFile? ... //Sound set up func setupAudio() { do { let session = AVAudioSession.sharedInstance() try session.setCategory(.playback, mode: .default, options: []) try session.setActive(true) } catch { print("Failed to configure AVAudioSession: \(error.localizedDescription)") } audioEngine = AVAudioEngine() environmentNode = AVAudioEnvironmentNode() playerNode = AVAudioPlayerNode() audioEngine.attach(environmentNode) audioEngine.attach(playerNode) audioEngine.connect(playerNode, to: environmentNode, format: nil) audioEngine.connect(environmentNode, to: audioEngine.mainMixerNode, format: nil) environmentNode.listenerPosition = AVAudio3DPoint(x: 0, y: 0, z: 0) environmentNode.listenerAngularOrientation = AVAudio3DAngularOrientation(yaw: 0, pitch: 0, roll: 0) environmentNode.distanceAttenuationParameters.referenceDistance = 1.0 environmentNode.distanceAttenuationParameters.maximumDistance = 100.0 environmentNode.distanceAttenuationParameters.rolloffFactor = 2.0 // example.mp3 is mono sound guard let audioURL = Bundle.main.url(forResource: "example", withExtension: "mp3") else { print("Audio file not found") return } do { audioFile = try AVAudioFile(forReading: audioURL) } catch { print("Failed to load audio file: \(error)") } } ... //Playing sound func playSpatialAudio(pan: Float ) { guard let audioFile = audioFile else { return } // left side playerNode.position = AVAudio3DPoint(x: pan, y: 0, z: 0) playerNode.scheduleFile(audioFile, at: nil, completionHandler: nil) do { try audioEngine.start() playerNode.play() } catch { print("Failed to start audio engine: \(error)") } ... } Second more complex approach using PHASE did better. I’ve made an exemplary app that allows players to move audio player in 3D space. I have added reverb, and sliders changing audio position up to 10 meters each direction from listener but audio seems to only really change left to right (x axis) - again I think it might be trouble with the app not being recognized as spatial. //Crucial class Variables: class PHASEAudioController: ObservableObject{ private var soundSourcePosition: simd_float4x4 = matrix_identity_float4x4 private var audioAsset: PHASESoundAsset! private let phaseEngine: PHASEEngine private let params = PHASEMixerParameters() private var soundSource: PHASESource private var phaseListener: PHASEListener! private var soundEventAsset: PHASESoundEventNodeAsset? // Initialization of PHASE init{ do { let session = AVAudioSession.sharedInstance() try session.setCategory(.playback, mode: .default, options: []) try session.setActive(true) } catch { print("Failed to configure AVAudioSession: \(error.localizedDescription)") } // Init PHASE Engine phaseEngine = PHASEEngine(updateMode: .automatic) phaseEngine.defaultReverbPreset = .mediumHall phaseEngine.outputSpatializationMode = .automatic //nothing helps // Set listener position to (0,0,0) in World space let origin: simd_float4x4 = matrix_identity_float4x4 phaseListener = PHASEListener(engine: phaseEngine) phaseListener.transform = origin phaseListener.automaticHeadTrackingFlags = .orientation try! self.phaseEngine.rootObject.addChild(self.phaseListener) do{ try self.phaseEngine.start(); } catch { print("Could not start PHASE engine") } audioAsset = loadAudioAsset() // Create sound Source // Sphere soundSourcePosition.translate(z:3.0) let sphere = MDLMesh.newEllipsoid(withRadii: vector_float3(0.1,0.1,0.1), radialSegments: 14, verticalSegments: 14, geometryType: MDLGeometryType.triangles, inwardNormals: false, hemisphere: false, allocator: nil) let shape = PHASEShape(engine: phaseEngine, mesh: sphere) soundSource = PHASESource(engine: phaseEngine, shapes: [shape]) soundSource.transform = soundSourcePosition print(soundSourcePosition) do { try phaseEngine.rootObject.addChild(soundSource) } catch { print ("Failed to add a child object to the scene.") } let simpleModel = PHASEGeometricSpreadingDistanceModelParameters() simpleModel.rolloffFactor = rolloffFactor soundPipeline.distanceModelParameters = simpleModel let samplerNode = PHASESamplerNodeDefinition( soundAssetIdentifier: audioAsset.identifier, mixerDefinition: soundPipeline, identifier: audioAsset.identifier + "_SamplerNode") samplerNode.playbackMode = .looping do {soundEventAsset = try phaseEngine.assetRegistry.registerSoundEventAsset( rootNode: samplerNode, identifier: audioAsset.identifier + "_SoundEventAsset") } catch { print("Failed to register a sound event asset.") soundEventAsset = nil } } //Playing sound func playSound(){ // Fire new sound event with currently set properties guard let soundEventAsset else { return } params.addSpatialMixerParameters( identifier: soundPipeline.identifier, source: soundSource, listener: phaseListener) let soundEvent = try! PHASESoundEvent(engine: phaseEngine, assetIdentifier: soundEventAsset.identifier, mixerParameters: params) soundEvent.start(completion: nil) } ... } Also worth mentioning might be that I only own personal team account
4
0
1.3k
Nov ’25
Regression: RealityKit spatial audio crackles and pops on iOS 26.0 beta 5 (FB19423059)
RealityKit spatial audio crackles and pops on iOS 26.0 beta 5. It works correctly on iOS 18.6 and visionOS 26.0 beta 5. The APIs used are AudioPlaybackController, Entity.prepareAudio, Entity.play Videos of the expected and observed behavior are attached to the feedback FB19423059. The audio should be a consistent, repeating sound, but it seems oddly abbreviated and the volume varies unexpectedly. Thank you for investigating this issue.
0
0
442
Aug ’25
RealityKit generates an excessive amount of logging
During regular use, RealityKit generates an excessive amount of internal logging that is not actionable by third party developers. When developing an iOS RealityKit/ARKit app, this makes the Xcode console challenging to use for regular work. (FB19173812) See screenshots below. Xcode does have an option for filtering out logging from specific SDKs, but enabling this feature to suppress the logging of RealityKit and related SDKs like PHASE is something developers have to do dozens of times each day. After a year of developing a RealityKit app, this process becomes frustrating. If SDKs like Foundation, UIKit, and SwiftUI generated as much logging as RealityKit and related SDKs, Xcode's console would be unusable. Is there any way to disable the logging of RealityKit and PHASE permanently? Thank you for any help you provide.
1
0
802
Jul ’25
Integrating Spatial Audio
I'm looking for a sample code project on integrating Spatial Audio into my app, Tunda Island, a music-loving, make friends and dating app. I have gone as far as purchasing a book "Exploring MusicKit" by Rudrank Riyam but to no avail.
1
0
891
Jul ’24
PHASE on Vision OS 2.0 beta in Unity
Hi, I'm looking to implement PHASEStreamNode in Unity, but the current provided PHASE library for Unity doesn't contain this new typos of nodes yet. https://developer.apple.com/documentation/phase/phasestreamnode When you will be looking into releasing the beta of the Unity Plugins as well? This is very important for spatial audio in Unity to be consistent with Apple's standards. Best, Antonio
1
1
859
Jul ’24
Spatial music-based navigation.
Hey, I've developed a new audio-based navigation technology for my Master's project at Imperial College London. The main aim of it is to take away the need for an annoying voice based prompt to interrupt your music ("Turn left in 300 yards"). Instead I've created a more natural interaction where the listener's music is binaurally spatialised to provide less annoying directional information. I've tested the product with many users and the feedback has been really positive! I just wondered whether anyone knew someone at Apple that I could have a chat with about this technology? I think it would work great if it was linked to Apple Maps, especially now with the integration of head-tracking into the Airpod Pro's.
0
0
727
May ’24
failed to start VoiceProcessingIO AudioUnit on VisionPro (os 1.1.1)
Hello, We are trying to use an audio calling functionality for visionOS with no success since the update of visionOS. We do not used CallKit for this flow. We set the AudioSession as followed: [sessionInstance setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeVoiceChat options: (AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP | AVAudioSessionCategoryOptionMixWithOthers) error:&error_]; We are creating our Audio unit as followed: AudioComponentDescription desc_; desc_.componentType = kAudioUnitType_Output; desc_.componentSubType = kAudioUnitSubType_VoiceProcessingIO; desc_.componentManufacturer = kAudioUnitManufacturer_Apple; desc_.componentFlags = 0; desc_.componentFlagsMask = 0; AudioComponent comp_ = AudioComponentFindNext(NULL, &desc_); IMSXThrowIfError(AudioComponentInstanceNew(comp_, &_audioUnit),"couldn't create a new instance of Apple Voice Processing IO."); UInt32 one_ = 1; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, audioUnitElementIOInput, &one_, sizeof(one_)), "could not enable input on Apple Voice Processing IO"); IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, audioUnitElementIOOutput, &one_, sizeof(one_)), "could not enable output on Apple Voice Processing IO"); IMSTagLogInfo(kIMSTagAudio, @"Rate: %ld", _rate); bool isInterleaved = _channel == 2 ? true : false; self.ioFormat = CAStreamBasicDescription(_rate, _channel, CAStreamBasicDescription::kPCMFormatInt16, isInterleaved); IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &_ioFormat, sizeof(self.ioFormat)), "couldn't set the input client format on Apple Voice Processing IO"); IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &_ioFormat, sizeof(self.ioFormat)), "couldn't set the output client format on Apple Voice Processing IO"); UInt32 maxFramesPerSlice_ = 4096; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFramesPerSlice_, sizeof(UInt32)), "couldn't set max frames per slice on Apple Voice Processing IO"); UInt32 propSize_ = sizeof(UInt32); IMSXThrowIfError(AudioUnitGetProperty(self.audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFramesPerSlice_, &propSize_), "couldn't get max frames per slice on Apple Voice Processing IO"); AURenderCallbackStruct renderCallbackStruct_; renderCallbackStruct_.inputProc = playbackCallback; renderCallbackStruct_.inputProcRefCon = (__bridge void *)self; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Output, 0, &renderCallbackStruct_, sizeof(renderCallbackStruct_)), "couldn't set render callback on Apple Voice Processing IO"); AURenderCallbackStruct inputCallbackStruct_; inputCallbackStruct_.inputProc = recordingCallback; inputCallbackStruct_.inputProcRefCon = (__bridge void *)self; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Input, 0, &inputCallbackStruct_, sizeof(inputCallbackStruct_)), "couldn't set render callback on Apple Voice Processing IO"); And as soon as we try to start the AudioUnit we have the following error: PhaseIOImpl.mm:1514 phaseextio@0x107a54320: failed to start IO directions 0x3, num IO streams [1, 1]: Error Domain=com.apple.coreaudio.phase Code=1346924646 "failed to pause/resume stream 6B273F5B-D6EF-41B3-8460-0E34B00D10A6" UserInfo={NSLocalizedDescription=failed to pause/resume stream 6B273F5B-D6EF-41B3-8460-0E34B00D10A6} We do not use PHASE framework on our side and the error is not clear to us nor documented anywhere. We also try to use a AudioUnit that only do Speaker witch works perfectly, but as soon as we try to record from an AudioUnit the start failed as well with the error AVAudioSessionErrorCodeCannotStartRecording We suppose that somehow inside PHASE an IO VOIP audio unit is running that prevent us from stoping/killing it when we try to create our own, and stop the whole flow. It used to work on visonOS 1.0.1 Regards, Summit-tech
0
0
1.2k
Mar ’24
PHASE Engine crashing when creating occluders from some MDLMeshes
hi there, i'm running into issues when creating occluders from arbitrary MDLMeshes (i.e. 3d models i create in app and then turn into MDLMeshes, rather than MDLMesh.newBox() etc). some meshes work fine, others hit an assert deep in the PHASE c++ code. i've tested on simulator and iPhone 12 (iOS16 and now iOS17 beta 3). i've tried to figure out if there's some kind of pattern to which meshes work and which don't, but haven't been able to find one. note that using the build in MDLMesh primitives works fine. the assert is: Assertion failed: (voxelIndex < level.mVoxels.Count()), function AddBuilderVoxelToSubtree, file GeoVoxelTree.cpp, line 188. the code is: func createOccluder(from meshes: [MDLMesh], at transform: Transform, preset: PHASEMaterialPreset) throws -> PHASEOccluder { guard let engine else { throw "No engine" } print("audio meshes: \(meshes)") let material = PHASEMaterial(engine: engine, preset: preset) var shapes: [PHASEShape] = [] for (_, mesh) in meshes.enumerated() { let meshShape = PHASEShape(engine: engine, mesh: mesh) for element in meshShape.elements { element.material = material } shapes.append(meshShape) } let occluder = PHASEOccluder(engine: engine, shapes: shapes) occluder.worldTransform = transform.matrix try engine.rootObject.addChild(occluder) return occluder } the assert happens with: let occluder = PHASEOccluder(engine: engine, shapes: shapes) any ideas on what could be going on here? cheers, Mike screenshots of callstack etc:
0
0
785
Jul ’23
Phase PushStreamNode audio format
I am currently building an app using PHASE, and I am using a PUSHStreamNode as an asset since the audio data I am using is coming from a stream. I produce from this stream 1 channel, 48kHz sample rate pcm buffers. I can create the node and the event, but when I start the engine (without even providing any data to the streams), I get the following error: Fatal Action tree data error: push stream data has invalid audio format, layoutTag = 0x0. I tried changing the format provided to PHASEPushStreamNodeDefinition, but it didn't help. Is there a specific AVAudioFormat that I need to use? My code to create the PushStreamNode: let source = PHASESource(engine: self.engine) do { try self.engine.rootObject.addChild(source)} catch { print("Failed to add a source to the scene") } let mixer = PHASESpatialMixerDefinition( spatialPipeline: PHASESpatialPipeline( flags: .directPathTransmission)! ) let model = PHASEGeometricSpreadingDistanceModelParameters() model.rolloffFactor = 1.0 mixer.distanceModelParameters = model let pushStreamNode = PHASEPushStreamNodeDefinition(mixerDefinition: mixer, format: AVAudioFormat(standardFormatWithSampleRate: 48000.0, channels: 1)!) var soundEventAsset: PHASESoundEventNodeAsset! do { soundEventAsset = try self.engine.assetRegistry.registerSoundEventAsset( rootNode: pushStreamNode, identifier: "mic_stream" ) } catch { print("Failed to register the sound event asset") return nil } let mixerParameters = PHASEMixerParameters() mixerParameters.addSpatialMixerParameters( identifier: mixer.identifier, source: source, listener: self.listener! ) var event: PHASESoundEvent! do { event = try PHASESoundEvent( engine: self.engine, assetIdentifier: soundEventAsset.identifier, mixerParameters: mixerParameters ) } catch { print("Failed to create the sound event \(error)") return nil }
1
2
964
Jun ’23
Settings listenerDirectivityModelParameters unexpected behavior
Hello, when I use listenerDirectivityModelParameters: let simpleCone = PHASEConeDirectivityModelParameters(subbandParameters: sub) spatialMixerDefinition.listenerDirectivityModelParameters = simpleCone I have to flip my listener around like so: listener!.transform = position * Transform(yaw: .pi, roll: .pi).matrix Without listenerDirectivityModelParameters everything works as expected. For example distanceModelParameters or sourceDirectivityModelParameters work fine with a listener position of: listener!.transform = position I found no way of getting the rotation or transform matrix of the cone or cardoid. So im kinda stuck with this solution right now.
0
0
699
Jan ’23
Is RealityKit in any way compatible with the PHASE Audio Engine?
Hi guys, Is RealityKit in any way compatible with the PHASE Audio Engine? It seems like RealityKit has its own audio engine which is not interchangeable. Or is there any way to stream the audio output from RealityKit into PHASE? And would that be smart? It makes me wonder. Because I thought RealityKit is the video simulation part of a game engine and PHASE the audio simulation part. Greetings Gabe
0
1
1.4k
Dec ’22
Detecting Spatialize Stereo
Ref: https://support.apple.com/en-mide/HT211775 The guide above outlines how a user can turn on spatial audio on an Apple device: Touch and hold the volume control to turn on spatial audio while you're playing multichannel content or Spatialize Stereo while you're playing two-channel stereo content. This also shows you the status icons. I have a couple of questions about this: Is there anything in any developer API that allows an app to detect when a user has chosen to listen to two-channel stereo content using "Spatialize Stereo". Likewise, is there any developer API that allows an app to disable this setting if it's been switched on by the user. Thanks for your help in advance, Ceri Hughes
2
0
1k
Nov ’22
Memory Management of 3D Audio Using the PHASE Framework
I am using 3D audio in space using the phase framework. Therefore, I am using sound echoes, etc. So I am using the following code to play the audio. final class PhaseManager {   private var engine: PHASEEngine!   private var listener: PHASEListener!       init() {     engine = PHASEEngine(updateMode: .automatic)     engine.outputSpatializationMode = .alwaysUseChannelBased     engine.defaultReverbPreset = .mediumRoom           listener = PHASEListener(engine: engine)     listener.transform = matrix_identity_float4x4     try? engine.rootObject.addChild(listener)     try? engine.start()   }       func play() {     let spatialPipelineFlags: PHASESpatialPipeline.Flags = [.directPathTransmission, .lateReverb]     let spatialPipeline = PHASESpatialPipeline(flags: spatialPipelineFlags)!           let spatialMixerDefinition = PHASESpatialMixerDefinition(spatialPipeline: spatialPipeline)           let joinSoundId = "\(Int.random(in: 0..<Int.max))"           let audioFileUrl = Bundle.main.url(forResource: "sound", withExtension: "mp3")!           let soundAsset = try! engine.assetRegistry.registerSoundAsset(       url: audioFileUrl,       identifier: joinSoundId,       assetType: .resident,       channelLayout: nil,       normalizationMode: .dynamic)           let samplerNodeDefinition = PHASESamplerNodeDefinition(       soundAssetIdentifier: soundAsset.identifier,       mixerDefinition: spatialMixerDefinition     )     samplerNodeDefinition.playbackMode = .oneShot           let soundEventAsset = try! engine.assetRegistry.registerSoundEventAsset(rootNode: samplerNodeDefinition, identifier: nil)           let source = PHASESource(engine: engine)     source.gain = 0.02     source.transform = matrix_identity_float4x4           try! engine.rootObject.addChild(source)           let mixerParameters = PHASEMixerParameters()     mixerParameters.addSpatialMixerParameters(identifier: spatialMixerDefinition.identifier, source: source, listener: listener)           let soundEvent = try! PHASESoundEvent(engine: engine, assetIdentifier: soundEventAsset.identifier, mixerParameters: mixerParameters)           soundEvent.start { [weak self] _ in       self?.engine.assetRegistry.unregisterAsset(identifier: joinSoundId) { _ in }     }   } } let manager = PhaseManager() manager.play() After playback is complete, memory is not released even though unregisterAsset is executed. manager.play() is performed repeatedly and t the memory is increasing proportionally. Is there any way to free the memory? I have already confirmed that removing the .lateReverb flag or setting source.gain = 1 will free memory, but that does not do what I want to achieve.
0
0
835
Mar ’22
How to use multichannel audio in TVOS using SceneKit
I tried to run multiple demos utilising spatial audio. However no matter what I do, I only get 2 channel output. Which is also confirmed by calling:       let numHardwareOutputChannels = gameView.audioEngine.outputNode.outputFormat(forBus: 0).channelCount My appleTV is connected to DolbyAtmos capable audio system which works just fine. So my question is more less - how to convince TVOS app that my appleTV has multichannel output ?!
0
0
982
Feb ’22
Feedback on Apple Spatial Audio re-render behavior for Dolby Atmos music delivery — perspective from a working mix engineer
Hey everyone, quick disclaimer before jumping in - I used my LLM to structure this around notes/observations I've been taking the last several months. I apologize for the length but felt this was the best distillation of an important challenge my peers and I are facing in mixing music for the largest device/service segment of the listening community - Airpods Pro/Max via Apple Music. Thanks in advance for reading and any feedback you can offer! -Kyle I'm a professional mix engineer working primarily in contemporary pop, indie, and country. After 20+ years of working in stereo, I've started delivering Dolby Atmos ADM masters for Apple Music distribution. I want to share some specific observations about the Apple Spatial Audio re-render in the hope that it's useful to the team that owns this rendering pipeline — and to ask a few questions I haven't been able to find answered in public documentation. I recognize this sits at an unusual intersection of the developer platform and the Apple Music delivery side of the house, but since the rendering behavior is ultimately a platform-level decision, this felt like the right place to start. Background: the three-format problem When delivering an Atmos ADM master, a mixer effectively has to satisfy three distinct listening contexts simultaneously: Speaker playback (7.1.4 or similar) via the Dolby renderer Dolby binaural re-render (AC-4), as heard on TIDAL and Amazon — which respects the OFF/NEAR/MID/FAR binaural mode settings on beds and objects Apple Spatial Audio headphone re-render on Apple Music The first two have reasonably predictable translation. The third is where I'm running into consistent issues — and where I'd value any guidance Apple is able to share. The core issue: Apple's re-render discards binaural mode metadata As best I can tell from testing and from community documentation, Apple's pipeline ingests the ADM, creates an internal 7.1.4 render, and then applies its own proprietary binaural spatialization — one that does not reference the OFF/NEAR/MID/FAR binaural mode parameters embedded by the mixer. This is distinct from the Dolby AC-4 path, which does honor those settings. In practice, this means: Apple's re-render applies a consistent room character regardless of what the mixer has specified for individual elements Elements like lead vocals and kick/snare — which I'm routing through beds or objects with OFF or NEAR binaural settings specifically to preserve intimacy and punch — receive the same ambient room treatment as wider, more spacious elements The result on Apple Music has noticeably more perceived distance and "room" on transient-heavy and close-mic'd elements than either the speaker mix or the Dolby binaural render To be specific about the perceptual effect: the Apple re-render's virtual room introduces early reflections and a sense of speaker-to-listener distance that significantly undercuts the intimacy and impact of close elements. On a pop or country vocal, this is the difference between a performance that feels present and direct versus one that feels recessed in a listening space. On drums, transient attack is softened in a way that doesn't happen in any other delivery context for the same master. Questions for the team I'd be grateful for any clarity on the following: Is the behavior of ignoring OFF/NEAR/MID/FAR metadata intentional and permanent, or is it something that may change as the rendering pipeline evolves? Is there any mechanism — existing or planned — by which a mixer can influence the room character or "closeness" of elements in Apple's re-render, outside of object positioning metadata? Is there any documentation of how Apple's binaural spatialization layer translates object distance metadata (as opposed to binaural mode) — i.e., does Z-axis positioning in the Atmos object space affect perceived distance in the re-render? Is there a recommended workflow or set of delivery parameters that Apple's audio team considers optimal for music content specifically, as opposed to film/TV? Notes on the Audiomovers Binaural Renderer for Apple Music I'm aware of and have used the Audiomovers plugin, which I understand was developed in collaboration with Apple and accurately reflects the Apple Spatial re-render during session monitoring. It's a genuinely useful tool and has improved my ability to anticipate Apple's output. My questions above are about the underlying rendering behavior — not the monitoring workflow, which is solved. Why this matters for music specifically Film and TV post content has different expectations around spatialization — a consistent room or "cinema" quality to the binaural render is arguably appropriate for that material. For music, particularly in contemporary genres where the stereo mix is already highly produced and intimate, an added room layer competes with the mix's own space design and consistently pushes elements further from the listener than intended. I'd argue music content would benefit from a rendering mode with a more "dry" or near-field room character — and I suspect I'm not alone in this among working Atmos music mixers. I'm happy to provide specific A/B examples or additional technical detail if that's useful to anyone on the platform team. Thanks for reading.
Replies
0
Boosts
1
Views
181
Activity
2w
I built apple.PHASE with Unity and targeted with visionOS, but Reverb does not sound.
Environment Versions ・macOS15.6.1 ・visionOS26.0.1 ・Xcode16.1 or 26.0.1 ・unity6000.2.9f1 ・Apple.core3.2.0 ・Apple.PHASE1.2.7 ・polyspatial2.4.2 With the above environment, after installing Apple.PHASE into unity and building to a visionOS device, Audio is available and distance attention works, but Early Reflection and Late Reverb produce no audible change even when checked and their parameters are adjusted. What is required to make Early Reflection and Late Reverb take effect on a visionOS device build? action taken ・created a SoundEvent. ・in composer, created a Sampler and a SpatialMixer; attached an AudioClip to the Sampler; enabled Direct Path, Early Reflection, and Late Reverb on the SpatialMixer. ・attached a PHASE Source to the object to be played, attached the created SoundEvent to it, and set non-zero values for Early Reflection and Late Reverb. ・attached a PHASE Listener to the mainCamera and set the ReverbPreset to a value other than None. ・in project settings > Audio, set Spatializer plugin to PHASE Spatializer. ・from there, build for visionOS.
Replies
0
Boosts
0
Views
913
Activity
Nov ’25
Spatial Audio on iOS 18 don't work as inteneded
I’m facing a problem while trying to achieve spatial audio effects in my iOS 18 app. I have tried several approaches to get good 3D audio, but the effect never felt good enough or it didn’t work at all. Also what mostly troubles me is I noticed that AirPods I have doesn’t recognize my app as one having spatial audio (in audio settings it shows "Spatial Audio Not Playing"). So i guess my app doesn't use spatial audio potential. First approach uses AVAudioEnviromentNode with AVAudioEngine. Chaining position of player as well as changing listener’s doesn’t seem to change anything in how audio plays. Here's simple how i initialize AVAudioEngine import Foundation import AVFoundation class AudioManager: ObservableObject { // important class variables var audioEngine: AVAudioEngine! var environmentNode: AVAudioEnvironmentNode! var playerNode: AVAudioPlayerNode! var audioFile: AVAudioFile? ... //Sound set up func setupAudio() { do { let session = AVAudioSession.sharedInstance() try session.setCategory(.playback, mode: .default, options: []) try session.setActive(true) } catch { print("Failed to configure AVAudioSession: \(error.localizedDescription)") } audioEngine = AVAudioEngine() environmentNode = AVAudioEnvironmentNode() playerNode = AVAudioPlayerNode() audioEngine.attach(environmentNode) audioEngine.attach(playerNode) audioEngine.connect(playerNode, to: environmentNode, format: nil) audioEngine.connect(environmentNode, to: audioEngine.mainMixerNode, format: nil) environmentNode.listenerPosition = AVAudio3DPoint(x: 0, y: 0, z: 0) environmentNode.listenerAngularOrientation = AVAudio3DAngularOrientation(yaw: 0, pitch: 0, roll: 0) environmentNode.distanceAttenuationParameters.referenceDistance = 1.0 environmentNode.distanceAttenuationParameters.maximumDistance = 100.0 environmentNode.distanceAttenuationParameters.rolloffFactor = 2.0 // example.mp3 is mono sound guard let audioURL = Bundle.main.url(forResource: "example", withExtension: "mp3") else { print("Audio file not found") return } do { audioFile = try AVAudioFile(forReading: audioURL) } catch { print("Failed to load audio file: \(error)") } } ... //Playing sound func playSpatialAudio(pan: Float ) { guard let audioFile = audioFile else { return } // left side playerNode.position = AVAudio3DPoint(x: pan, y: 0, z: 0) playerNode.scheduleFile(audioFile, at: nil, completionHandler: nil) do { try audioEngine.start() playerNode.play() } catch { print("Failed to start audio engine: \(error)") } ... } Second more complex approach using PHASE did better. I’ve made an exemplary app that allows players to move audio player in 3D space. I have added reverb, and sliders changing audio position up to 10 meters each direction from listener but audio seems to only really change left to right (x axis) - again I think it might be trouble with the app not being recognized as spatial. //Crucial class Variables: class PHASEAudioController: ObservableObject{ private var soundSourcePosition: simd_float4x4 = matrix_identity_float4x4 private var audioAsset: PHASESoundAsset! private let phaseEngine: PHASEEngine private let params = PHASEMixerParameters() private var soundSource: PHASESource private var phaseListener: PHASEListener! private var soundEventAsset: PHASESoundEventNodeAsset? // Initialization of PHASE init{ do { let session = AVAudioSession.sharedInstance() try session.setCategory(.playback, mode: .default, options: []) try session.setActive(true) } catch { print("Failed to configure AVAudioSession: \(error.localizedDescription)") } // Init PHASE Engine phaseEngine = PHASEEngine(updateMode: .automatic) phaseEngine.defaultReverbPreset = .mediumHall phaseEngine.outputSpatializationMode = .automatic //nothing helps // Set listener position to (0,0,0) in World space let origin: simd_float4x4 = matrix_identity_float4x4 phaseListener = PHASEListener(engine: phaseEngine) phaseListener.transform = origin phaseListener.automaticHeadTrackingFlags = .orientation try! self.phaseEngine.rootObject.addChild(self.phaseListener) do{ try self.phaseEngine.start(); } catch { print("Could not start PHASE engine") } audioAsset = loadAudioAsset() // Create sound Source // Sphere soundSourcePosition.translate(z:3.0) let sphere = MDLMesh.newEllipsoid(withRadii: vector_float3(0.1,0.1,0.1), radialSegments: 14, verticalSegments: 14, geometryType: MDLGeometryType.triangles, inwardNormals: false, hemisphere: false, allocator: nil) let shape = PHASEShape(engine: phaseEngine, mesh: sphere) soundSource = PHASESource(engine: phaseEngine, shapes: [shape]) soundSource.transform = soundSourcePosition print(soundSourcePosition) do { try phaseEngine.rootObject.addChild(soundSource) } catch { print ("Failed to add a child object to the scene.") } let simpleModel = PHASEGeometricSpreadingDistanceModelParameters() simpleModel.rolloffFactor = rolloffFactor soundPipeline.distanceModelParameters = simpleModel let samplerNode = PHASESamplerNodeDefinition( soundAssetIdentifier: audioAsset.identifier, mixerDefinition: soundPipeline, identifier: audioAsset.identifier + "_SamplerNode") samplerNode.playbackMode = .looping do {soundEventAsset = try phaseEngine.assetRegistry.registerSoundEventAsset( rootNode: samplerNode, identifier: audioAsset.identifier + "_SoundEventAsset") } catch { print("Failed to register a sound event asset.") soundEventAsset = nil } } //Playing sound func playSound(){ // Fire new sound event with currently set properties guard let soundEventAsset else { return } params.addSpatialMixerParameters( identifier: soundPipeline.identifier, source: soundSource, listener: phaseListener) let soundEvent = try! PHASESoundEvent(engine: phaseEngine, assetIdentifier: soundEventAsset.identifier, mixerParameters: params) soundEvent.start(completion: nil) } ... } Also worth mentioning might be that I only own personal team account
Replies
4
Boosts
0
Views
1.3k
Activity
Nov ’25
Regression: RealityKit spatial audio crackles and pops on iOS 26.0 beta 5 (FB19423059)
RealityKit spatial audio crackles and pops on iOS 26.0 beta 5. It works correctly on iOS 18.6 and visionOS 26.0 beta 5. The APIs used are AudioPlaybackController, Entity.prepareAudio, Entity.play Videos of the expected and observed behavior are attached to the feedback FB19423059. The audio should be a consistent, repeating sound, but it seems oddly abbreviated and the volume varies unexpectedly. Thank you for investigating this issue.
Replies
0
Boosts
0
Views
442
Activity
Aug ’25
RealityKit generates an excessive amount of logging
During regular use, RealityKit generates an excessive amount of internal logging that is not actionable by third party developers. When developing an iOS RealityKit/ARKit app, this makes the Xcode console challenging to use for regular work. (FB19173812) See screenshots below. Xcode does have an option for filtering out logging from specific SDKs, but enabling this feature to suppress the logging of RealityKit and related SDKs like PHASE is something developers have to do dozens of times each day. After a year of developing a RealityKit app, this process becomes frustrating. If SDKs like Foundation, UIKit, and SwiftUI generated as much logging as RealityKit and related SDKs, Xcode's console would be unusable. Is there any way to disable the logging of RealityKit and PHASE permanently? Thank you for any help you provide.
Replies
1
Boosts
0
Views
802
Activity
Jul ’25
Is there any way to disable PHASE/CoreAudio logging?
Is there a way to permanently disable PHASE SDK logging? It seems to be a lot chattier than Apple's other SDKs. While developing a RealityKit app that uses AudioPlaybackController, I must manually hide the PHASE SDK log output several times each day so I can see my app's log messages. Thank you.
Replies
0
Boosts
0
Views
512
Activity
Jun ’25
Phase Audio and Unity
Does Phase support creating new sound events at runtime? Is that implemented in the plugin for Unity as well? Does Phase support Unity's addressable system, are they compatible?
Replies
0
Boosts
0
Views
518
Activity
Dec ’24
Publishing iPhone app that uses external sensor data
My team and I have created an iPhone application that receives and utilizes sensor data from a separate raspberrypi-powered device. The iPhone app does not function without the use of the sensor data. How will the App Reviewers be able to test the application when submitting to the App Store?
Replies
1
Boosts
0
Views
717
Activity
Aug ’24
Integrating Spatial Audio
I'm looking for a sample code project on integrating Spatial Audio into my app, Tunda Island, a music-loving, make friends and dating app. I have gone as far as purchasing a book "Exploring MusicKit" by Rudrank Riyam but to no avail.
Replies
1
Boosts
0
Views
891
Activity
Jul ’24
PHASE on Vision OS 2.0 beta in Unity
Hi, I'm looking to implement PHASEStreamNode in Unity, but the current provided PHASE library for Unity doesn't contain this new typos of nodes yet. https://developer.apple.com/documentation/phase/phasestreamnode When you will be looking into releasing the beta of the Unity Plugins as well? This is very important for spatial audio in Unity to be consistent with Apple's standards. Best, Antonio
Replies
1
Boosts
1
Views
859
Activity
Jul ’24
Spatial music-based navigation.
Hey, I've developed a new audio-based navigation technology for my Master's project at Imperial College London. The main aim of it is to take away the need for an annoying voice based prompt to interrupt your music ("Turn left in 300 yards"). Instead I've created a more natural interaction where the listener's music is binaurally spatialised to provide less annoying directional information. I've tested the product with many users and the feedback has been really positive! I just wondered whether anyone knew someone at Apple that I could have a chat with about this technology? I think it would work great if it was linked to Apple Maps, especially now with the integration of head-tracking into the Airpod Pro's.
Replies
0
Boosts
0
Views
727
Activity
May ’24
failed to start VoiceProcessingIO AudioUnit on VisionPro (os 1.1.1)
Hello, We are trying to use an audio calling functionality for visionOS with no success since the update of visionOS. We do not used CallKit for this flow. We set the AudioSession as followed: [sessionInstance setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeVoiceChat options: (AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP | AVAudioSessionCategoryOptionMixWithOthers) error:&error_]; We are creating our Audio unit as followed: AudioComponentDescription desc_; desc_.componentType = kAudioUnitType_Output; desc_.componentSubType = kAudioUnitSubType_VoiceProcessingIO; desc_.componentManufacturer = kAudioUnitManufacturer_Apple; desc_.componentFlags = 0; desc_.componentFlagsMask = 0; AudioComponent comp_ = AudioComponentFindNext(NULL, &desc_); IMSXThrowIfError(AudioComponentInstanceNew(comp_, &_audioUnit),"couldn't create a new instance of Apple Voice Processing IO."); UInt32 one_ = 1; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, audioUnitElementIOInput, &one_, sizeof(one_)), "could not enable input on Apple Voice Processing IO"); IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, audioUnitElementIOOutput, &one_, sizeof(one_)), "could not enable output on Apple Voice Processing IO"); IMSTagLogInfo(kIMSTagAudio, @"Rate: %ld", _rate); bool isInterleaved = _channel == 2 ? true : false; self.ioFormat = CAStreamBasicDescription(_rate, _channel, CAStreamBasicDescription::kPCMFormatInt16, isInterleaved); IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &_ioFormat, sizeof(self.ioFormat)), "couldn't set the input client format on Apple Voice Processing IO"); IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &_ioFormat, sizeof(self.ioFormat)), "couldn't set the output client format on Apple Voice Processing IO"); UInt32 maxFramesPerSlice_ = 4096; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFramesPerSlice_, sizeof(UInt32)), "couldn't set max frames per slice on Apple Voice Processing IO"); UInt32 propSize_ = sizeof(UInt32); IMSXThrowIfError(AudioUnitGetProperty(self.audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFramesPerSlice_, &propSize_), "couldn't get max frames per slice on Apple Voice Processing IO"); AURenderCallbackStruct renderCallbackStruct_; renderCallbackStruct_.inputProc = playbackCallback; renderCallbackStruct_.inputProcRefCon = (__bridge void *)self; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Output, 0, &renderCallbackStruct_, sizeof(renderCallbackStruct_)), "couldn't set render callback on Apple Voice Processing IO"); AURenderCallbackStruct inputCallbackStruct_; inputCallbackStruct_.inputProc = recordingCallback; inputCallbackStruct_.inputProcRefCon = (__bridge void *)self; IMSXThrowIfError(AudioUnitSetProperty(self.audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Input, 0, &inputCallbackStruct_, sizeof(inputCallbackStruct_)), "couldn't set render callback on Apple Voice Processing IO"); And as soon as we try to start the AudioUnit we have the following error: PhaseIOImpl.mm:1514 phaseextio@0x107a54320: failed to start IO directions 0x3, num IO streams [1, 1]: Error Domain=com.apple.coreaudio.phase Code=1346924646 "failed to pause/resume stream 6B273F5B-D6EF-41B3-8460-0E34B00D10A6" UserInfo={NSLocalizedDescription=failed to pause/resume stream 6B273F5B-D6EF-41B3-8460-0E34B00D10A6} We do not use PHASE framework on our side and the error is not clear to us nor documented anywhere. We also try to use a AudioUnit that only do Speaker witch works perfectly, but as soon as we try to record from an AudioUnit the start failed as well with the error AVAudioSessionErrorCodeCannotStartRecording We suppose that somehow inside PHASE an IO VOIP audio unit is running that prevent us from stoping/killing it when we try to create our own, and stop the whole flow. It used to work on visonOS 1.0.1 Regards, Summit-tech
Replies
0
Boosts
0
Views
1.2k
Activity
Mar ’24
PHASE Engine crashing when creating occluders from some MDLMeshes
hi there, i'm running into issues when creating occluders from arbitrary MDLMeshes (i.e. 3d models i create in app and then turn into MDLMeshes, rather than MDLMesh.newBox() etc). some meshes work fine, others hit an assert deep in the PHASE c++ code. i've tested on simulator and iPhone 12 (iOS16 and now iOS17 beta 3). i've tried to figure out if there's some kind of pattern to which meshes work and which don't, but haven't been able to find one. note that using the build in MDLMesh primitives works fine. the assert is: Assertion failed: (voxelIndex < level.mVoxels.Count()), function AddBuilderVoxelToSubtree, file GeoVoxelTree.cpp, line 188. the code is: func createOccluder(from meshes: [MDLMesh], at transform: Transform, preset: PHASEMaterialPreset) throws -> PHASEOccluder { guard let engine else { throw "No engine" } print("audio meshes: \(meshes)") let material = PHASEMaterial(engine: engine, preset: preset) var shapes: [PHASEShape] = [] for (_, mesh) in meshes.enumerated() { let meshShape = PHASEShape(engine: engine, mesh: mesh) for element in meshShape.elements { element.material = material } shapes.append(meshShape) } let occluder = PHASEOccluder(engine: engine, shapes: shapes) occluder.worldTransform = transform.matrix try engine.rootObject.addChild(occluder) return occluder } the assert happens with: let occluder = PHASEOccluder(engine: engine, shapes: shapes) any ideas on what could be going on here? cheers, Mike screenshots of callstack etc:
Replies
0
Boosts
0
Views
785
Activity
Jul ’23
Phase PushStreamNode audio format
I am currently building an app using PHASE, and I am using a PUSHStreamNode as an asset since the audio data I am using is coming from a stream. I produce from this stream 1 channel, 48kHz sample rate pcm buffers. I can create the node and the event, but when I start the engine (without even providing any data to the streams), I get the following error: Fatal Action tree data error: push stream data has invalid audio format, layoutTag = 0x0. I tried changing the format provided to PHASEPushStreamNodeDefinition, but it didn't help. Is there a specific AVAudioFormat that I need to use? My code to create the PushStreamNode: let source = PHASESource(engine: self.engine) do { try self.engine.rootObject.addChild(source)} catch { print("Failed to add a source to the scene") } let mixer = PHASESpatialMixerDefinition( spatialPipeline: PHASESpatialPipeline( flags: .directPathTransmission)! ) let model = PHASEGeometricSpreadingDistanceModelParameters() model.rolloffFactor = 1.0 mixer.distanceModelParameters = model let pushStreamNode = PHASEPushStreamNodeDefinition(mixerDefinition: mixer, format: AVAudioFormat(standardFormatWithSampleRate: 48000.0, channels: 1)!) var soundEventAsset: PHASESoundEventNodeAsset! do { soundEventAsset = try self.engine.assetRegistry.registerSoundEventAsset( rootNode: pushStreamNode, identifier: "mic_stream" ) } catch { print("Failed to register the sound event asset") return nil } let mixerParameters = PHASEMixerParameters() mixerParameters.addSpatialMixerParameters( identifier: mixer.identifier, source: source, listener: self.listener! ) var event: PHASESoundEvent! do { event = try PHASESoundEvent( engine: self.engine, assetIdentifier: soundEventAsset.identifier, mixerParameters: mixerParameters ) } catch { print("Failed to create the sound event \(error)") return nil }
Replies
1
Boosts
2
Views
964
Activity
Jun ’23
profesional audio spatial audio
If one were working on a multi billion dollar project what is the best way to get help and involvement or potential implementations of apple spatial support regarding apple spatial audio support. We are aiming for AES69.
Replies
0
Boosts
0
Views
814
Activity
Feb ’23
Settings listenerDirectivityModelParameters unexpected behavior
Hello, when I use listenerDirectivityModelParameters: let simpleCone = PHASEConeDirectivityModelParameters(subbandParameters: sub) spatialMixerDefinition.listenerDirectivityModelParameters = simpleCone I have to flip my listener around like so: listener!.transform = position * Transform(yaw: .pi, roll: .pi).matrix Without listenerDirectivityModelParameters everything works as expected. For example distanceModelParameters or sourceDirectivityModelParameters work fine with a listener position of: listener!.transform = position I found no way of getting the rotation or transform matrix of the cone or cardoid. So im kinda stuck with this solution right now.
Replies
0
Boosts
0
Views
699
Activity
Jan ’23
Is RealityKit in any way compatible with the PHASE Audio Engine?
Hi guys, Is RealityKit in any way compatible with the PHASE Audio Engine? It seems like RealityKit has its own audio engine which is not interchangeable. Or is there any way to stream the audio output from RealityKit into PHASE? And would that be smart? It makes me wonder. Because I thought RealityKit is the video simulation part of a game engine and PHASE the audio simulation part. Greetings Gabe
Replies
0
Boosts
1
Views
1.4k
Activity
Dec ’22
Detecting Spatialize Stereo
Ref: https://support.apple.com/en-mide/HT211775 The guide above outlines how a user can turn on spatial audio on an Apple device: Touch and hold the volume control to turn on spatial audio while you're playing multichannel content or Spatialize Stereo while you're playing two-channel stereo content. This also shows you the status icons. I have a couple of questions about this: Is there anything in any developer API that allows an app to detect when a user has chosen to listen to two-channel stereo content using "Spatialize Stereo". Likewise, is there any developer API that allows an app to disable this setting if it's been switched on by the user. Thanks for your help in advance, Ceri Hughes
Replies
2
Boosts
0
Views
1k
Activity
Nov ’22
Memory Management of 3D Audio Using the PHASE Framework
I am using 3D audio in space using the phase framework. Therefore, I am using sound echoes, etc. So I am using the following code to play the audio. final class PhaseManager {   private var engine: PHASEEngine!   private var listener: PHASEListener!       init() {     engine = PHASEEngine(updateMode: .automatic)     engine.outputSpatializationMode = .alwaysUseChannelBased     engine.defaultReverbPreset = .mediumRoom           listener = PHASEListener(engine: engine)     listener.transform = matrix_identity_float4x4     try? engine.rootObject.addChild(listener)     try? engine.start()   }       func play() {     let spatialPipelineFlags: PHASESpatialPipeline.Flags = [.directPathTransmission, .lateReverb]     let spatialPipeline = PHASESpatialPipeline(flags: spatialPipelineFlags)!           let spatialMixerDefinition = PHASESpatialMixerDefinition(spatialPipeline: spatialPipeline)           let joinSoundId = "\(Int.random(in: 0..<Int.max))"           let audioFileUrl = Bundle.main.url(forResource: "sound", withExtension: "mp3")!           let soundAsset = try! engine.assetRegistry.registerSoundAsset(       url: audioFileUrl,       identifier: joinSoundId,       assetType: .resident,       channelLayout: nil,       normalizationMode: .dynamic)           let samplerNodeDefinition = PHASESamplerNodeDefinition(       soundAssetIdentifier: soundAsset.identifier,       mixerDefinition: spatialMixerDefinition     )     samplerNodeDefinition.playbackMode = .oneShot           let soundEventAsset = try! engine.assetRegistry.registerSoundEventAsset(rootNode: samplerNodeDefinition, identifier: nil)           let source = PHASESource(engine: engine)     source.gain = 0.02     source.transform = matrix_identity_float4x4           try! engine.rootObject.addChild(source)           let mixerParameters = PHASEMixerParameters()     mixerParameters.addSpatialMixerParameters(identifier: spatialMixerDefinition.identifier, source: source, listener: listener)           let soundEvent = try! PHASESoundEvent(engine: engine, assetIdentifier: soundEventAsset.identifier, mixerParameters: mixerParameters)           soundEvent.start { [weak self] _ in       self?.engine.assetRegistry.unregisterAsset(identifier: joinSoundId) { _ in }     }   } } let manager = PhaseManager() manager.play() After playback is complete, memory is not released even though unregisterAsset is executed. manager.play() is performed repeatedly and t the memory is increasing proportionally. Is there any way to free the memory? I have already confirmed that removing the .lateReverb flag or setting source.gain = 1 will free memory, but that does not do what I want to achieve.
Replies
0
Boosts
0
Views
835
Activity
Mar ’22
How to use multichannel audio in TVOS using SceneKit
I tried to run multiple demos utilising spatial audio. However no matter what I do, I only get 2 channel output. Which is also confirmed by calling:       let numHardwareOutputChannels = gameView.audioEngine.outputNode.outputFormat(forBus: 0).channelCount My appleTV is connected to DolbyAtmos capable audio system which works just fine. So my question is more less - how to convince TVOS app that my appleTV has multichannel output ?!
Replies
0
Boosts
0
Views
982
Activity
Feb ’22