I've searched this error and I haven't found anyone with the same error. I'm pretty sure I know what this error means, but I don't know how to avoid it.
Basically what's happening is I have a phone call over MultipeerConnectivity. I'm using an AVAudioEngine to record audio and play audio from the peer.
I've noticed that there was a pretty big delay between the time that the user was talking and the time it would take for the other device to play that audio, but I fixed the issue by removing the tap and reinstalling it. This completely removes any delay. However, sometimes it throws an error.
I also allow the user to mute their mic, and when they click mute, the tap is removed. Once they click unmute, the tap is reinstalled. Again sometimes this also throws the same error:
AVAudioEngineGraph.mm:2707: InputAvailable: required condition is false: NULL != tap
This error seems to be completely random though. Sometimes it happens, other times it doesn't. I haven't been able to consistently reproduce the error.
My guess is that this is because it's trying to install a tap where a tap already exists, but I don't know how to avoid it. I guess I could just increment the bus that the tap is being installed on, but this doesn't seem like the best option.
I also looked to see if there was a property on AVAudioInputNode that would tell me if there was already a tap installed on a particular bus, but I didn't seem to find any.
Does anyone have any experience with this issue?
If you find a better solution then please let me know what it is. This is not a 100% complete solution, but it was the best I could find with the little help I received on the problem.
I found somewhat of a workaround, however there is likely still a better solution. This doesn't completely remove the problem, I've seen the issue once or twice since I've made the change, but it definitely reduces the chances of it happening.
Basically what I did was when I remove a tap, make sure to wait until it is finished before allowing the installation of a tap. In my case, I had a mute button, and I made sure to not allow the user to touch the button faster than the tap could be removed. So as soon as the button is touched, I don't allow any presses until the tap is removed, and then reactivate the button.
Secondly, I'm not sure that this does anything at all, but before installing a tap on the inputNode, I always call inputNode.reset() and then inputNode.removeTap(onBus: 0) first, and then install the tap.
inputNode.reset()
inputNode.removeTap(onBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 4096, format: localInputFormat) {
...
}