Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

com.apple.coreaudio.avfaudio - player did not see an IO cycle. #2910

Open
Volodymyr-13 opened this issue Apr 15, 2024 · 3 comments
Open

com.apple.coreaudio.avfaudio - player did not see an IO cycle. #2910

Volodymyr-13 opened this issue Apr 15, 2024 · 3 comments
Labels

Comments

@Volodymyr-13
Copy link

Volodymyr-13 commented Apr 15, 2024

macOS Version(s) Used to Build

macOS 14.4.1 (23E224)

Xcode Version(s)

Xcode 15

Description

Hello,

In our Firebaze logs, we frequently encounter the error message "player did not see an IO cycle."
In our application, we have diligently followed the Apple guidelines outlined in the "Audio Guidelines for User-Controlled Playback and Recording Apps" document (https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioGuidelinesByAppType/AudioGuidelinesByAppType.html#//apple_ref/doc/uid/TP40007875-CH11-SW1).
To address this issue, we have implemented handling for the following states:
• AVAudioSession.interruptionNotification
• AVAudioSession.routeChangeNotification
• UIApplication.didEnterBackgroundNotification
• UIApplication.willEnterForegroundNotification
Additionally, we have referred to resources such as the following Stack Overflow thread for insights (https://stackoverflow.com/questions/74889075/avaudioplayernode-play-causes-crash-after-backgrounding-and-foregrounding-the).
We understand that upon route changes or transitions between background and foreground app states, it is necessary to rebuild our engine. Therefore, we have incorporated the method engine.rebuildGraph() to address these scenarios.
However, despite these measures, we continue to encounter the "player did not see an IO cycle" crash. Compounding the issue, we have only observed this crash in Firebase logs, and we have been unable to replicate it during our own testing.
Could you kindly provide some guidance or advice on resolving this issue?
Thank you.

Screenshot

Crash Logs, Screenshots or Other Attachments (if applicable)

Fatal Exception: com.apple.coreaudio.avfaudio
0 CoreFoundation 0x83f24 __exceptionPreprocess
1 libobjc.A.dylib 0x16018 objc_exception_throw
2 CoreFoundation 0x18266c +[NSException raise:format:]
3 AVFAudio 0x44cc AVAE_RaiseException(NSString*, ...)
4 AVFAudio 0xf0120 AVAudioPlayerNodeImpl::StartImpl(AVAudioTime*)
5 AVFAudio 0x493c AVAudioNodeImplBase::Start(AVAudioTime*)
6 AVFAudio 0xec804 -[AVAudioPlayerNode play]
7 App 0x84e324 AudioPlayer.play(from:to:at:completionCallbackType:completionHandler:) + 44 (AudioPlayer+Playback.swift:44)
8 App 0x16836c AudioPlayer.playerPlay() + 558 (AudioPlayer.swift:558)
9 App 0x123e54 partial apply for closure #1 in PlayerViewModel.play() + 185 (PlayerViewModel.swift:185)
10 App 0x20baf0 thunk for @escaping @callee_guaranteed @sendable () -> () ()
11 libdispatch.dylib 0x213c _dispatch_call_block_and_release
12 libdispatch.dylib 0x3dd4 _dispatch_client_callout
13 libdispatch.dylib 0x6f6c _dispatch_queue_override_invoke
14 libdispatch.dylib 0x15894 _dispatch_root_queue_drain
15 libdispatch.dylib 0x1609c _dispatch_worker_thread2
16 libsystem_pthread.dylib 0x48f8 _pthread_wqthread
17 libsystem_pthread.dylib 0x10cc start_wqthread

@jcavar
Copy link
Contributor

jcavar commented Apr 16, 2024

I've ran into this as well. Here is a snippet that reproduces a problem which might help you understand if you are doing something similar:

let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
engine.attach(player)
engine.connect(player, to: engine.mainMixerNode, format: nil)
let format = AVAudioFormat(standardFormatWithSampleRate: 44100, channels: 2)!
let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: 100)!
player.scheduleBuffer(buffer)
engine.mainMixerNode.auAudioUnit.inputBusses[0].isEnabled = false
try! engine.start()
player.play()
player.play(at: AVAudioTime(sampleTime: 0, atRate: 44100))

The root cause is that you are not allowed to start a player if it is in active audio chain.

@kunalzigma
Copy link

kunalzigma commented May 21, 2024

Hello, @Volodymyr-13 & @jcavar , am seeing same crashes.

0x192112b28 __exceptionPreprocess + 164 (NSException.m:249)
1 libobjc.A.dylib 0x189fe6f78 objc_exception_throw + 60 (objc-exception.mm:356)
2 CoreFoundation 0x192198234 +[NSException raise:format:arguments:] + 96 (NSException.m:0)
3 AVFAudio 0x1abafea84 AVAE_RaiseException(NSString*, ...) + 52 (AVAEInternal.h:69)
4 AVFAudio 0x1abbeb230 AVAudioPlayerNodeImpl::StartImpl(AVAudioTime*) + 2524 (AVAudioPlayerNode.mm:660)
5 AVFAudio 0x1abafeef4 AVAudioNodeImplBase::Start(AVAudioTime*) + 64 (AVAudioNodeImpl.h:176)
6 AVFAudio 0x1abbe7914 -[AVAudioPlayerNode play] + 68 (AVAudioPlayerNode.mm:1138)
7 AudioApp 0x10285f534 AudioPlayer.play(from:to:at:completionCallbackType:) + 2444 (AudioPlayer+Playback.swift:43)

But don't know where am going wrong where am starting the player when it is in active audio chain. Like am seeing 0.2% sessions with this errors because of this. Cannot reproduce it.
Is it possible that the code avoids starting the player when it is active audio chain? Like it does not do anything and not crash? Will be huge win for us as this is the only crash, we are seeing. Currently running app on AudioKit 5.6.4 using SPM.

@NickCulbertson
Copy link
Member

I've noticed that you sometimes can't restart the engine immediately after route changes or interruptions. In those cases, I reload everything on a delay. I'm not rebuilding the graph like you, but maybe the solution of adding a delay will do the trick. It might also be possible that the crash is occurring when the application is being exited entirely.

    func reloadAudio() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            if !conductor.engine.avEngine.isRunning {
                conductor.selectSound(conductor.currentSound)
                try? conductor.engine.start()
            }
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants