ottijp blog

AVAudioEngineでオーディオにエフェクトをかける

2020-09-22 Tags: XCodeAVAudioEngineSwift

環境

  • 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で簡単にオーディオにエフェクトがかけられることがわかりました.


ottijp
Satoshi SAKAO (@ottijp)

都内でアプリケーションエンジニアをしています

...