AudioKit 入门教程

原文:AudioKit Tutorial: Getting Started
作者:Colin Eberhardt
同时感谢:kmyhy


近来手上有一些音频相关的开发工作,搜搜基Hub,目前最为强大,性能屌爆,编码炫酷的开源库也只有AudioKit了。Raywenderlich也能找到相关教程,介于作者是3.0+的教程,很多代码都不能跑了,特此整理一趴。
本文不仅是一篇iOS开发教程,更是一篇精彩的科普文。关于编程与艺术的结合,声学物理与音乐的碰撞,尽在此文。推荐所有程序员都好好读一读它,让我们的生活除了代码,还有艺术,还有音乐。感谢作者Colin Eberhardt。

iOS 设备提供了丰富的多媒体体验,比如绚丽的视觉效果、声音和可触摸的交互界面。尽管能够使用各种各样的特性,但作为开发者,我们更多地关注了应用的视觉设计,而忽略了用户体验的声学效果。

AudioKit是一个高级音频框架,由声学设计师、程序员和音乐家为 iOS 专门打造。AudioKit底层混合了SwiftObjective-CC++C,负责和苹果音频已硬件的Api打交道。所有神奇(同时十分复杂的)技术都封装成为极其友好的 Swift Api ,你甚至可以直接在XcodePlayground中使用它。

本文无法全面覆盖 AudioKit 的知识点。相反,我们会通过介绍声音合成和计算机声频的历史,来带你进行一次有趣和时尚的 AudioKit 之旅。通过这种方式,你会学到基本的声学物理,了解早期的合成器比如电子琴是如何工作的。最终来到现代,一个大混音时代。

请给自己来一杯咖啡,拖过一张椅子,开始我们的旅程!

AudioKit 入门教程_第1张图片
image

开始

原教程的原始内容使用的是 3.4.0 版本,用的是Playground做案例,本文使用最新的 4.3.0 ,用Xcode创建的Swift项目做案例。

港真,教程的第一步并不是特别鸡冻的。为了在 Playground 中使用 AudioKit,我们必须提前进行一些准备工作。

我们需要先到AudioKit下源码AudioKit-4.3,或者自行clone:

git clone https://github.com/AudioKit/AudioKit.git

解压好后用Terminal进入AudioKit-4.3文件夹执行编译命令:

$ cd Frameworks
$ ./build_frameworks.sh

编译时间较长(14的顶配编译的近十分钟吧),你阔以继续阅读,或者撸一把,或者鸡一把。

一定要编译完成,编译好后进入Playgrounds文件,打开下面的AudioKitPlaygrounds.xcodeproj,这里我们就阔以看官方为我们写好的示例代码,提前体验一把 AudioKit 的强大。体验完了别忘了纸巾,进入正题开始教程之旅。

AudioKit 入门教程_第2张图片
image

新建一个名为JorneryPlayground。录入一下代码:

import AudioKitPlaygrounds
import AudioKit


let oscillator = AKOscillator()

AudioKit.output = oscillator
try? AudioKit.start()

oscillator.start()

sleep(10)

编译时,你会听到大约 10 秒钟的蜂鸣声。你可以点击 Playground 调试窗口左下角的 Play/Stop 按钮停止或运行 Playground。

注意:建议打开工程的时候就直接Command + B编译一遍,再跑想看的代码。如果 Playground 执行出错,并在 Debug 窗口中出现错误,你可以重启 Xcode。不幸的是,当 Playground 和框架一起使用时,总是容易出现一些小问题,并且无法预知。
另外建议把 Run 方式改为 Manually RunAutomatically Run太容易故障了。

振荡器和声学基础

人类通过物体制造音乐——通过击打、拖拉或者弹奏等形式——有数千年的历史。我们的许多民族乐器,比如鼓、吉他,已经发明几个世纪了。电子乐器的第一个次使用记录,或者是第一次通过电路发声,是 1874 年 Elisha Gray 创下的,他从事电信行业。Elisha 发明了振荡器,最原始的声音合成装置,你的探索将从这个东西开始。

右键点击 Playground,选择 New Playground Page,创建一个新的 Playground 文件 Oscillators

将 Xcode 产生的代码替换为:

import AudioKitPlaygrounds
import AudioKit


// 1. Create an oscillator
let oscillator = AKOscillator()

// 2. Start the AudioKit 'engine'
AudioKit.output = oscillator
try? AudioKit.start()

// 3. Start the oscillator
oscillator.start()


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

这个 Playground 将没完没了地发出哔哔声——呃,有意思。你可以按 Stop 来停止它。
这和前面创建的测试 Playground 差不多,但这次我们将深入讨论细节。
代码分成了几个步骤:

  • 创建一个 AudioKit 振荡器,它是一个 AKNode 子类。节点是构成你的音频序列的主要元素。
  • 将 AudioKit 引擎和你最终输出的节点关联起来,在这里这个节点是你唯一的节点。音频引擎就像物理引擎或游戏引擎:你必须启动它并让它持续运转,这样你的音频序列才能被执行。
  • 最后,打开振荡器,它会发出一条声波。

一个振荡器会创建一个重复的、或者周期性的无限延续的信号。在这个 Playground 中,AKOscillator 发出了一个正弦波。这个数字化的正弦波经过 AudioKit 处理,直接输出到你的扬声器或者耳麦,导致真正的振荡器以同样的正弦波进行振荡。声音通过压缩你耳朵周围的空气传播到你耳中,最终你就听到了这个烦人的啸叫声!

AudioKit 入门教程_第3张图片
image

有两个参数决定了振荡器发出的声音是什么样子:amplitude - 振幅,它是正弦波的高度并决定声音的大小,以及 frequency - 频率,它决定了音高。
在你的 Playground 中,在创建振荡器之后加入这两句:

oscillator.frequency = 300
oscillator.amplitude = 0.5

倾听一会,你会发现现在的音量只是刚才的一半,而且音高也比刚才低了。频率单位为赫兹(即每秒周期数),决定了音符的音高。而振幅,范围从 0-1 ,决定了音量。
Elisha Gray 在专利官司中输给了Alexander Graham Bell,失去了成为电话机发明者的机会。但是,他的偶然发明振荡器却导致第一个电子乐器专利的产生。

AudioKit 入门教程_第4张图片
image

许多年以后,Léon Theremin 发明了一个怪异的电子乐器,至今仍然被使用着。使用特雷门琴,你可以在这个乐器上方挥舞手臂来改变电子振荡器的频率。如果你不知道怎么形容这个乐器发出的声音,我建议你听一听 The Beach Boys 演唱的 Good Vibrations, 这首歌曲中特雷门琴所发出的独特声音令人记忆深刻。

你可以在 Playground 的最后加入以下代码模拟这种效果:

oscillator.rampDuration = 0.2
oscillator.frequency = 500


import AudioKitUI

AKPlaygroundLoop(every: 0.5) {
    oscillator.frequency = (oscillator.frequency == 500 ? 100 : 500)
}

rampDuration 属性允许振荡器在属性值之间平滑过渡(比如频率或振幅)。AKPlaygroundLoop 是一个很有用的实用函数,允许周期性地执行 Playground 中的代码。在这里,你简单滴每 0.5 秒就切换一次振荡器的频率,从 500Hz 到 100 Hz。

你制造了自己的特雷门琴!

简单的振荡器可以发出音符,但是并不能令耳朵愉悦。真正的乐器还受许多别的因素的影响,比如钢琴,它的声音很独特。在后面几节中,你会继续探索它们是如何形成的。
完整代码:

import AudioKitPlaygrounds
import AudioKit


let oscillator = AKOscillator()
oscillator.frequency = 300
oscillator.amplitude = 0.5

AudioKit.output = oscillator
try? AudioKit.start()

oscillator.start()

oscillator.rampDuration = 0.2
oscillator.frequency = 500


import AudioKitUI

AKPlaygroundLoop(every: 0.5) {
    oscillator.frequency = (oscillator.frequency == 500 ? 100 : 500)
}


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

声音封包

当乐器演奏出一个音符时,振幅(或音量)是会变化的,并且每个乐器都不相同。有一个能够模拟这个效果的模型,叫做 Attack-Decay-Sustain-Release (ADSR) 封包:

AudioKit 入门教程_第5张图片
image

这个封包由几个部分构成:

  • Attack - 上行: 在这个阶段声音上行至最大音量。
  • Decay - 下行: 这个时候声音下滑到 Sustain 水平。
  • Sustain - 维持: 这个阶段声音会维持在释放终止时的音量,一直到开始 Release。
  • Release - 释放: 这个阶段音量开始下滑到 0。

一台钢琴,当琴弦被木锤敲击,会发出一个非常短促的上行音然后迅速下降。一把小提琴则会发出比较长的上行、下行和维持,因为演奏时琴弓不会离开琴弦。
电子琴是第一批电子乐器中使用 ADSR 封包的乐器之一。这种乐器发明于 1939 年,由 163 个电子管和 1000 多个特制的电容器构成,重达 500 英磅(230 kg)。但不幸的是,只制造了 1000 台电子琴,它没有获得商业上的成功。

AudioKit 入门教程_第6张图片
image

图片来自于 courtesy of Hollow Sun – 遵循 CC attribution 协议。

右键单击 Playground 中的顶层元素,Journey,选择 New Playground Page ,创建一个新的 Playground 叫做ADSR。编辑文件内容为:

import AudioKitPlaygrounds
import AudioKit


let oscillator = AKOscillator()

创建了一个振荡器,这个你已经很熟悉了。然后继续加入代码:

let envelope = AKAmplitudeEnvelope(oscillator)
envelope.attackDuration = 0.01
envelope.decayDuration = 0.1
envelope.sustainLevel = 0.1
envelope.releaseDuration = 0.3

这次创建了一个 AKAmplitudeEnvelope 并定义了一个 ADSR 封包。durantion 参数用秒为单位指定,level 参数指定的是音量,取值访问 0-1 之间。
AKAmplitudeEnvelope 是 AKNode 子类,同 AKOscillator 一样。在上面的代码中,你可以看到,振荡器作为参数被传递给了封包的构造函数,两个节点连在了一起。
接着:

AudioKit.output = envelope
try? AudioKit.start()

oscillator.start()

AudioKit 引擎启动,这次将输出改成 ADSR 封包,然后打开振荡器。

AudioKit 入门教程_第7张图片
image

为了听到封包效果,你必须重复播放封包,然后停止封包:

import AudioKitUI

AKPlaygroundLoop(every: 0.5) {
    if (envelope.isStarted) {
        envelope.stop()
    } else {
        envelope.start()
    }
}


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

现在你会听到同一个音符被反复播放,但这次带上了声音封包效果,听起来有点钢琴的味道了。
每秒播放两次,每个循环都以 ADSR 开始和结束。当循环开始后,快速上行到最大音量,这个过程大约 0.01 秒,紧接着是 0.1 秒的下行,到达维持水平。这个过程约 0.5 秒,然后释放 0.3 秒。
修改 ADSR 值,尝试创建其他声音的效果。试试如何模拟小提琴?
从振荡器发出正弦波开始到现在,已经过去很长时间了。当你用振荡器演奏音符的同时,会使用 ADSR 去让声音更加柔和,但你仍然不能把它称之为真正的音乐!
下一节,你会学习如何创建更加丰富的声音。
完整代码:

import AudioKitPlaygrounds
import AudioKit


let oscillator = AKOscillator()

let envelope = AKAmplitudeEnvelope(oscillator)
envelope.attackDuration = 0.01
envelope.decayDuration = 0.1
envelope.sustainLevel = 0.1
envelope.releaseDuration = 0.3

AudioKit.output = envelope
try? AudioKit.start()

oscillator.start()


import AudioKitUI

AKPlaygroundLoop(every: 0.5) {
    if (envelope.isStarted) {
        envelope.stop()
    } else {
        envelope.start()
    }
}


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

声音叠加合成

每种乐器都有独一无二的音质,并以其音色而得名。这就是为什么钢琴的声音和小提琴的声音截然不同的原因,哪怕它们演奏同一个音符。音色的一个重要属性是乐器所产生的声谱。声谱表示乐器发出一个单音符时所组成的频率范围。你的 Playground 当前所用的振荡器只能发出单一的频率,所以听起来非常假。
通过将一系列振荡器合并在一起作为输出并演奏同一个音符,你能够真实地模拟出一个乐器。这就是“叠加合成”。这是你的下一个课题。

右键单击 Playground,选择 New Playground Page 创建新的页,叫做Additive Synthesis,编辑如下代码:

import AudioKitPlaygrounds
import AudioKit

func createAndStartOscillator(frequency: Double) -> AKOscillator {
    let oscillator = AKOscillator()
    oscillator.frequency = frequency
    return oscillator
}

对于叠加合成,你需要使用多个振荡器。createAndStartOscillator 方法用于创建它们。
然后写入:

let frequencies = (1...5).map { $0 * 261.63 }

这里用了一个 Range 操作来创建一个从 1 到 5 的序列。然后对这个序列进行 map 操作,将每个数字乘以 261.63。这个数字是标注键盘上的中音 C 的音频。将其他数字乘以这个值,这就是“和声”。

然后继续加入:

let oscillators = frequencies.map {
    createAndStartOscillator(frequency: $0)
}

再次进行一个 map 操作,以创建多个振荡器。
然后将它们合成在一起。加入:

let mixer = AKMixer()
oscillators.forEach { mixer.connect(input: $0) }

AKMixer 类也是 AudioKit 中的节点;
它将 1 个或多个节点作为输出并将它们合成在一起。
然后:

let envelope = AKAmplitudeEnvelope(mixer)
envelope.attackDuration = 0.01
envelope.decayDuration = 0.1
envelope.sustainLevel = 0.1
envelope.releaseDuration = 0.3

AudioKit.output = envelope
try? AudioKit.start()

oscillators.map { $0.start() }


import AudioKitUI

AKPlaygroundLoop(every: 0.5) {
    if (envelope.isStarted) {
        envelope.stop()
    } else {
        envelope.start()
    }
}

上述代码你已经很熟悉了;它用 mixer 创建了一个 ADSR 封包,将它提供给 AudioKit 引擎,然后不停地播放和停止它。
要真正能够听出合成的效果,你可以尝试一下将这些频率进行不同的组合。当你尝试这样做的时候,Playground 的 live-view 是一个不错的工具!
加入下列代码:

class LiveView: AKLiveViewController {

    override func viewDidLoad() {
        addTitle("Mixer")

        oscillators.forEach { oscillator in
            let slider = AKSlider(property: "\(oscillator.frequency) Hz", value: oscillator.amplitude) { amplitude in
                oscillator.amplitude = amplitude
            }
            addView(slider)
        }
    }
}


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = LiveView()

AudioKit 有许多类允许你轻松创建交互式的 Playground;我们在这里也使用了其中几个。
LiveView 类是 AKLiveViewController 的子类,它由一系列垂直排列的 subview 组成。在 viewDidLoad 方法中,你遍历每个振荡器,为每个振荡器创建一个 AKSlider。每个 Slider 用每个振荡器的频率和振幅进行初始化,当遍历到一个 slider 时,都可以为它设置一个回调块,这样当你拖动 slider 时回调块被执行。尾随闭包就是这个回调块,允许你修改每个振荡器的频率。通过这种简单的方式,你可以和 Playground 进行交互。

为了测试上述代码,你必须开启 live view。点击右上角的双环图标,打开助手窗口。同时将 live view 设置为正确的 playground 文件。

AudioKit 入门教程_第8张图片
image

你可以通过修改每个 Slider 的振幅来改变乐器的音色。为了获得更加自然的音质,我建议你参照上图来进行设置。

最早的一种采用叠加合成的合成器是 200 吨重的电传簧风琴。如此巨大的体量,立即宣告了这种乐器的消亡。结局更好的电子管风琴使用了类似的转速脉冲轮技术,但体积更小,用同样的加法合成实现了独特的声音。电传簧风琴在 1935 年发明,在前卫摇滚时代仍然是一种广为人知的流行乐器。

AudioKit 入门教程_第9张图片
image

C3 电传簧风琴 – 图片来自 public domain image。

转速脉冲轮上有旋转的轮盘,轮沿上有许多光滑的隆起,旋转轮盘附近有一个拾波器总成。电传簧风琴由许多这样的转速脉冲轮组成,它们以不同的速度旋转。音乐家通过拉杆来混合这些声音并产生一个音符。这种发声方式真的十分简陋,严格地讲,与其说是电子式的,不如说是机电式的。

要创建更真实的声谱有许多别的技术,比如 调频技术(FM)和脉宽调制技术(PWM),这两种在 AudioKit 中都可以通过AKFMOscillatorAKPWMOscillator类来实现。无疑,我将鼓励你去尝试这两者。为什么不在你的 Playground 中用这两者将 AKOscillator 替换掉呢?

复音

上个世纪 70 年代,出现了一种偏离模块化合成的理论,它使用单独的振荡器、封包和过滤器,并使用了微处理器。替代模拟电路,它使用了数字合成的方式发声。它导致了价格极其低廉和便携式合成器的出现,比如著名的雅马哈电子合成器,被专业和业余音乐爱好者广泛使用。

AudioKit 入门教程_第10张图片
image

1983 年的 Yamaha DX7 – 图片来自public domain image

你所有的 Playground 都被死死限制在只能一次演奏一个音符。如果使用多个乐器,音乐家可以同时演奏多个音符。这种演奏方式就叫做“复音”,相反,如果一次只能演奏一个音符,就像你的 Playground 一样,则叫做“单音”。
为了制造复音,你需要创建多个振荡器,每个振荡器演奏不同的音符,并通过一个 mixer 节点播放出来。但是,我们还有一种更简单的 方法:使用 AudioKit 的振荡器 bank。

右键单击 Playground,选择 New Playground Page 创建一个新的 page 就叫做Polyphony。写入以下代码:

import AudioKitPlaygrounds
import AudioKit

let bank = AKOscillatorBank()
AudioKit.output = bank
try? AudioKit.start()

这里创建了一个振荡器 bank,并将它作为 AudioKit 的输出。如果你按下 Command 键点击 AKOscilatorBank,你将看到它的类定义,你会发现它其实继承了 AKPolyphonicNode。如果你继续深究下去,你会发现它又继承了 AKNode 并采用了AKPolyphonic 协议。

因此,振荡器 bank 和其他 AudioKit 一样,它的输出也能够被 mixer、封包和其它滤镜和效果所加工。AKPolyphonic 协议描述了你应该如何在这个复音节点上演奏音符,等下你就知道了。

为了测试这个振荡器,你需要设法和谐地播放多个音符。这听起来好复杂?
在 Playground 后面加入下列代码,同时打开 live view:

import AudioKitUI

class LiveView: AKLiveViewController, AKKeyboardDelegate {

    override func viewDidLoad() {
        addTitle("Keyboard")
        let keyboard = AKKeyboardView(width: 440, height: 100)
        keyboard.delegate = self
        keyboard.polyphonicMode = true
        addView(keyboard)
    }

    func noteOn(note: MIDINoteNumber) {
        bank.play(noteNumber: note, velocity: 80)
    }

    func noteOff(note: MIDINoteNumber) {
        bank.stop(noteNumber: note)
    }
}


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = LiveView()

当 Playground 编译成功,你会看到这个:

AudioKit 入门教程_第11张图片
image

这么酷?一个 Playground 居然画出了一个音乐键盘?
AKKeyboardView 另外一个 AudioKit 提供的实用工具,它使这个框架真的容易使用和研究里面的功能。
当你按下一个键,键盘会调用 noteON 委托方法。方法的实现很简单,简单地播放了振荡器 bank。noteOff 方法则调用对应的 stop 方法。
点击并在键盘上滑动,你会发现它演奏出了优美的音阶。振荡器 bank 内置了 ADSR 支持。因此,一个音符的下行会和另一个音符的上升、松开和保持混在了一起,发出了令人愉悦的声音。

你可能注意到了,键盘提供的音符不再以频率的方式提供,而是以 MIDINoteNumber 类型提供。如果你按住 Command 键并点击左鼠键,查看它的定义,你会看到它只是一个整型:

public typealias MIDINoteNumber = Int

MIDI 标准全称是 Musical Instrument Digital Interface(乐器数字接口),它在乐器间进行通讯时广泛使用。 音符数字和标准键盘上的音符一一对应。play 方法的第二个参数 velocity 是另一个 MIDI 属性,用于描述一个音符的敲击力度。值越小表明敲击得越轻,会发出一个更小的声音。

最后一步是将键盘设置为复音模式。在 setup 方法代码最后中加入:

keyboard.polyphonicMode = true

你会发现现在可以同时演奏多个音符了,只需要这样:

AudioKit 入门教程_第12张图片
image

……太不可思议了,C-大调。这个项目使用了 Soundpipe,代码来自于 CSound,一个起始于 1985 年的 MIT 开源项目。令人不可思议的是它可以在 Playground 中运行并添加到你的 App 中,而它竟然拥有超过 30 年的历史了!

抽样

你已经学习了半天的声音合成技术了,在这个过程中你尝试用非常原始的方式制造拟真的声音:振荡器、过滤器和混合器。早在上世纪 70 年代,随着计算机处理能力和存储的增长,一种完全不同的方法出现了——声音取样——目标是制造声音的数字复制品。

取样是相对简单的概念,它和数字影像技术中的原理相同。自然声音是光滑的波形,取样只是在固定的时间间隔内简单地记录声波的震动:

AudioKit 入门教程_第13张图片
image

在抽样过程中,有两个因素直接影响了记录的拟真度:

  • Bit depth - 位深: 表示一个取样器能够复制的离散振幅数。
  • Sample rate - 速率: 表示多久进行一次振幅测量,单位是 Hz。

你将用另一个 Playground 来学习这些属性。
在 Playground 上右键,选择 New Playground Page 并创建新的 page 名为Samples。编辑如下代码:

import AudioKitPlaygrounds
import AudioKit

let file = try AKAudioFile(readFileName: "climax-disco-part2.wav", baseDir: .resources)
let player = try AKAudioPlayer(file: file)
player.looping = true

这段代码载入了一个示例音频,创建了一个声音播放器,并设置它的循环播放这个声音。
这个波表文件放在这个zip文件中。解压缩这个 zip 文件,将 WAV 文件拖到 Playground 的 resources 文件夹中。

然后,在 Playground 文件最后继续加入:

AudioKit.output = player
try? AudioKit.start()

player.play()


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

这会将你的声频播放器传递给 AudioKit 引擎并开始播放。调大音量,注意听。
这个简单的例子重复播放各种声音,这些声音很难用基本的振荡器来模拟。
正在使用的音频有一个比较高的位深和取样率,能够产生清脆和清晰的声音。为了试验这两个参数,在创建音频播放器之后,加入如下代码:

let bitcrusher = AKBitCrusher(player)
bitcrusher.bitDepth = 16
bitcrusher.sampleRate = 40000
AudioKit.output = bitcrusher

现在播放的声音就截然不同了:仍然是同一个抽样文件,但声音变得非常尖锐。
AKBitCrusher 是一种 AudioKit 音效,用于模拟低位深低取样率的效果。使用它,你可以制造出这种效果,就像是早期用 ZX Spectrum 或 BBC Micro 进行抽样的声音,这些电脑仅有几 Kb 的内存和处理器,比起如今的电脑来说要慢上几百万倍!

最后的实验,是将许多节点组合在一起,制造出立体声延迟效果。删除代码中用于创建和配置 bitcrusher 的三行代码。然后添加:

let delay = AKDelay(player)
delay.time = 0.1
delay.dryWetMix = 1

这会用你的抽样文件创建出大约 0.1 秒的延迟效果。干/湿混合值让你将延迟声音和未延迟的声音进行混合,设置为 1 表示只有经过延迟的声音被节点输出。
然后,加入代码:

let leftPan = AKPanner(player, pan: -1)
let rightPan = AKPanner(delay, pan: 1)

AKPanner 节点允许你将音频进行移动,左移、右移或者之间的某个地方。上述代码将延迟过的音频左移,为延迟的声音右移。
最后一个步骤是将两者混合在一起,并设置 AudioKit 的输出,用下面的代码替换掉原来设置 AudioKit 的输出为 bitcrusher 的代码:

let mix = AKMixer(leftPan, rightPan)
AudioKit.output = mix

这将播放同一个文件,但在左右扬声器之间有一个非常短的延迟。
完整代码:

import AudioKitPlaygrounds
import AudioKit

let file = try AKAudioFile(readFileName: "climax-disco-part2.wav", baseDir: .resources)
let player = try AKAudioPlayer(file: file)
player.looping = true

//let bitcrusher = AKBitCrusher(player)
//bitcrusher.bitDepth = 16
//bitcrusher.sampleRate = 40000
//AudioKit.output = bitcrusher

let delay = AKDelay(player)
delay.time = 0.1
delay.dryWetMix = 1

let leftPan = AKPanner(player, pan: -1)
let rightPan = AKPanner(delay, pan: 1)
let mix = AKMixer(leftPan, rightPan)

AudioKit.output = mix
try? AudioKit.start()

player.play()


import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true
AudioKit 入门教程_第14张图片
image

结语

在本教程中,你对“使用 AudioKit 能干什么”有了一个大致的理解了。开始探险吧——尝试一下穆格过滤,升降调、混响,或者图像均衡器的效果怎么样?
只需要一小点创意,你就可以制造出自己的声音、电子乐器或者游戏音效。

你可以下载最终项目。当然,你仍然还需要像最开始那样编译动态库,并将最终代码拖入进去即可。

最后,感谢 AudioKit 项目的Lead,Aurelius Prochazka,审阅了本文。

你可能感兴趣的:(AudioKit 入门教程)