AVAudioEngineでオーディオにエフェクトをかける
環境
- macOS: 10.15 (Catalina)
- iOS: 13.7
- Xcode: 12.0
背景
iOSDC2020で聞いたこちらのセッションが面白かったので,自分でも実装してみました.
今日から分かるAVAudioEngineの全て by meteor | トーク | iOSDC Japan 2020 - fortee.jp
今日から分かる AVAudioEngineの全て - Speaker Deck
やったこと
上記トークで紹介されていたことと同じことをやってみました. AVAudioEngineとAVAudioUnit(ディストーションとリバーブ)を使って,マイク入力にエフェクトをかけて通話用スピーカに出力しました.
XcodeでiOSアプリを新規作成し,次のようなビューコントローラを作成しました.
ViewController.swift
import UIKit
import AVFoundation
class ViewController: UIViewController {
var engine: AVAudioEngine!
var distortion: AVAudioUnitDistortion!
var reverb: AVAudioUnitReverb!
override func viewDidLoad() {
super.viewDidLoad()
// create audio engine and nodes
engine = AVAudioEngine()
distortion = AVAudioUnitDistortion()
reverb = AVAudioUnitReverb()
// initialize audio session
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
let ioBufferDuration = 128.0 / 44100.0
try AVAudioSession.sharedInstance().setPreferredIOBufferDuration(ioBufferDuration)
}
catch {
assertionFailure("AvAudioSettion setup error: \(error)")
}
// get input/output/format of audio engine
let input = engine.inputNode
let output = engine.outputNode
let format = input.inputFormat(forBus: 0)
// setup distortion
distortion.loadFactoryPreset(.drumsBitBrush)
distortion.preGain = 4.0
engine.attach(distortion)
// setup reverb
reverb.loadFactoryPreset(.mediumChamber)
reverb.wetDryMix = 80
engine.attach(reverb)
// connect audio nodes
engine.connect(input, to: distortion, format: format)
engine.connect(distortion, to: reverb, format: format)
engine.connect(reverb, to: output, format: format)
// start audio engine
do {
try engine.start()
}
catch {
assertionFailure("AVAudioEngine start error: \(error)")
}
}
}
使い方
iPhoneで普通に通話するようにマイクに向かってしゃべると,通話用スピーカからエフェクトのかかった音が聞こえます! 今回のコードでは,お風呂の中で喋ってるような反響音(ロボットボイス?)になります.面白いw
外部スピーカに出力してしまうとハウリングしてしまうので,自分の声にエフェクトをかけて再生する場合は,何かしらの工夫が要るのかな? とりあえず,AVAudioEngineで簡単にオーディオにエフェクトがかけられることがわかりました.