Open1
iOS:AVAudioEngineのsetVoiceProcessingでエラーが発生する件
iOSのAVAudioEngine
を使って、マイク入力&音声合成でインとアウトの両方を使うアプリを作っています。
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playAndRecord, mode: .voiceChat)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
こんな感じで、カテゴリを.playAndRecord
にして、モードを.voiceChat
(もしくは.videoChat
)にするとマイク入力と、音声出力の両方ができます。
で、音声合成をAVSpeechSynthesizer
で行う場合、AVAudioOutputNode
のsetVoiceProcessingEnabled(true)
をすると、再生音量が大きくできるみたいなのです。
(ドキュメントとかに書いてあるわけではなく、やってみたら大きくなった)
これをやらないととても小さな声で再生するので聞き取れません。
class MyClass {
private var audioEngine = AVAudioEngine()
func doSomething() throws {
let outputNode = self.audioEngine.outputNode
try outputNode.setVoiceProcessingEnabled(true)
// このあと何か音声合成する
}
}
ですが、音が大きくなる反面、エラーをめちゃくちゃ出力するようになります。
throwing -1
from AU (0x1068c61c0): auou/vpio/appl, render err: -1
このメッセージが実行中(AVAudioEngineがアクティブな間ずっと)Xcodeのログに出続けます。
(かつXcodeでデバッグ実行を止めると、このメッセージをどこかに出力しているのか、レインボーカーソルが回り続けて邪魔)
色々試したところ、ミキサーを追加してアウトプットに繋げばOKと分かりました。
func doSomething() throws {
let outputNode = self.audioEngine.outputNode
try outputNode.setVoiceProcessingEnabled(true)
let mainMixer = self.audioEngine.mainMixerNode
let outputFormat = outputNode.outputFormat(forBus: 0)
self.audioEngine.connect(mainMixer, to: outputNode, format: outputFormat)
Thread.sleep(forTimeInterval: 1.0)
// このあと何か音声合成する
}
最後のsleep
ですが、これを入れないとタイミング依存か何かで、うまく行くときと行かないときがあります(1.0が良いかはちょっと分かっていません)。うまく行かないときはマイク入力ができません(出力もできないような気がしますが試してはいません)。
ちなみにconnect
でインプットからミキサーに繋いでないのが気持ち悪い気もしますが、それをしたらマイク入力した音がアウトプットに出てくるので、今回の目的ではダメです。