iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
テキスト文書を読み上げ機能で再生した音声に、CoreAudioのAudio Unitを使ってエフェクトをかける方法を探っていきたいと思う。
まずは、Audio Unitについて調べてみる。
CoreAudioのAudio Unitで出来る事を調べるには、AU Labを使ってみるのが一番だ。
AU Labは、以下から入手できる。
読み上げるテキストを用意する。
自由に利用出来るテキストとして、小説『白鯨』がよく使われているが、日本語のテキストだと、青空文庫から入手するのがよいと思う。ただし、文字コードはUTF-8に、開業文字はLFにすること。
入手してテキストをsayコマンドで読み上げる。
$ say -n : -f ./風琴と魚の町.txt
AU Labを起動する。
"Create Document"を押下し、Editメニューで"Add Audio Unit Generator..."を選択し、AUNetReceiveを追加する。
AUNetReceiveの接続を押下する。
追加したGeneratorのEffectsを押下し、メニューでAUDistortionを選択する。
すると、ディストーションのパラメータが変更できるようになる。
次は、これをプログラムで行えるようにしてみる。
今回は、以前のアプリをSwift化するだけの内容だ。
テキストの内容を読み上げるが、それにディレイをかける。
import Cocoa
import AudioUnit
import AudioToolbox
import CoreAudioKit
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
demo()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
var auGraph: AUGraph? = nil
func demo() {
var inputNode: AUNode = 0
var effectNode: AUNode = 0
var outputNode: AUNode = 0
NewAUGraph(&auGraph);
var cd = AudioComponentDescription()
cd.componentType = kAudioUnitType_Generator
cd.componentSubType = kAudioUnitSubType_SpeechSynthesis
cd.componentManufacturer = kAudioUnitManufacturer_Apple
cd.componentFlags = 0
cd.componentFlagsMask = 0
AUGraphAddNode(auGraph!, &cd, &inputNode)
cd.componentType = kAudioUnitType_Effect
cd.componentSubType = kAudioUnitSubType_Delay
AUGraphAddNode(auGraph!, &cd, &effectNode)
cd.componentType = kAudioUnitType_Output
cd.componentSubType = kAudioUnitSubType_DefaultOutput
AUGraphAddNode(auGraph!, &cd, &outputNode)
AUGraphConnectNodeInput(auGraph!, inputNode, 0, effectNode, 0)
AUGraphConnectNodeInput(auGraph!, effectNode, 0, outputNode, 0)
AUGraphOpen(auGraph!)
AUGraphInitialize(auGraph!)
var generateAudioUnit: AudioUnit? = nil
AUGraphNodeInfo(auGraph!, inputNode, nil, &generateAudioUnit)
var channel: SpeechChannel? = nil
var sz: UInt32 = UInt32(MemoryLayout.size)
AudioUnitGetProperty(generateAudioUnit!, kAudioUnitProperty_SpeechChannel, kAudioUnitScope_Global, 0, &channel, &sz)
AUGraphStart(auGraph!)
SpeakCFString(channel!, "Nice to meet you. It's nice to see you! Nice meeting you. I'm pleased to meet you. Please say hello to your family. I look forward to seeing you again. Yes. Let's get together soon." as NSString, nil)
}
func dispose() {
AUGraphStop(auGraph!)
AUGraphUninitialize(auGraph!)
AUGraphClose(auGraph!)
DisposeAUGraph(auGraph!)
auGraph = nil
}
}