类似的音频库还有soundtouch,其中提供了 pitch、rate、tempo等来控制变速还是变调。
使用:
github上下载好之后,运行framework中的build_frameworks.sh(把文件移入终端)
之后会生成不同的framework文件,拖入项目中即可使用
xcode项目中的linker flags为 -lc++
Module compiled with Swift 4.1.2 cannot be imported by the Swift 4.2 compile
这是因为之前导入库的时候用的是4.1,而重新install只会去找podfile.lock中没有的库,所以还是原来的版本,因此用pod update 库名 就可以进行更新,不加名称就更新每一个
podfile.lock会锁定版本,不管有没有新的,install只安装lock中规定的,因此提交的时候最好把这个提交上去
notenum是速度,会变速也会变调 有些文件对应一个notenum 对于单一文件不能改变notenum
velocity是力度,越大声音越响
音符不再以频率的方式提供,而是以 MIDINoteNumber 类型提供。如果你按住 Command 键并点击左鼠键,查看它的定义,你会看到它只是一个整型:
public typealias MIDINoteNumber = Int
MIDI 标准全称是 Musical Instrument Digital Interface(乐器数字接口),它在乐器间进行通讯时广泛使用。 音符数字和标准键盘上的音符一一对应。play 方法的第二个参数 velocity 是另一个 MIDI 属性,用于描述一个音符的敲击力度。值越小表明敲击得越轻,会发出一个更小的声音。
//震荡子 是AKNode子类 node是构成你的音频序列的主要元素 一个振荡子会创建一个重复的、或者周期性的无限延续的信号。
let oscillator = AKOscillator()
有两个参数决定了振荡器发出的声音是什么样子:振幅,它是正弦波的高度并决定声音的大小,以及频率,它决定了音高。
oscillator.frequency = 300 频率(音高)
oscillator.amplitude = 0.5 振幅(音量)
倾听一会,你会发现现在的音量只是刚才的一半,而且音高也比刚才底了。频率单位为赫兹(即每秒周期数),决定了音符的音高。而振幅,范围从 0-1 ,决定了音量。
oscillator.rampDuration = 0.2
oscillator.frequency = 500
AKPlaygroundLoop(every: 0.5) {
oscillator.frequency =
oscillator.frequency == 500 ? 100 : 500
}
rampDuration(以前是time) 属性允许振荡器在属性值之间平滑过渡(比如频率或振幅)。AKPlaygroundLoop 是一个很有用的实用函数,允许周期性地执行 Playground 中的代码。在这里,你简单滴每 0.5 秒就切换一次振荡器的频率,从 500Hz 到 100 Hz。
ADSR
当乐器演奏出一个音符时,振幅(或音量)是会变化的,并且每个乐器都不相同。有一个能够模拟这个效果的模型,叫做 Attack-Decay-Sustain-Release (ADSR) 封皮:
Attack 上升: 在这个阶段声音上行至最大音量。
Decay 下行: 这个时候声音下滑到 Sustain 水平。
Sustain 维持: 这个阶段声音会维持在退败终止时的音量,一直到开始松开。
Release 松开: 这个阶段音量开始下滑到 0。
一台钢琴,当琴弦被木锤敲击,会发出一个非常短促的上升音然后迅速下降。一把小提琴则会发出比较长的上升、下行和维持,因为演奏时琴弓不会离开琴弦。
通过修改ADSR的值,可以模拟不同乐器的效果。
Additive Sound Synthesis(加法合成)
let frequencies = (1...5).map { $0 * 261.63 }
这里用了一个 Range 操作来创建一个从 1 到 5 的序列。然后对这个序列进行 map 操作,将每个数字乘以 261.63。这个数字是标注键盘上的中音 C 的音频。将其他数字乘以这个值,这就是“和声”。
//再次进行一个 map 操作,以创建多个振荡器。
let oscillators = frequencies.map {
createAndStartOscillator(frequency: $0)
}
let mixer = AKMixer()
oscillators.forEach { mixer.connect($0) }
AKMixer类是AudioKit的另一种节点.
它将 1 个或多个节点作为输出并将它们合成在一起。
后来发现要在AudioKit.start之后start才行,否则没有声音。
Polyphony(复音)
let bank = AKOscillatorBank()
AudioKit.output = bank
try? AudioKit.start()
let keyboard = AKKeyboardView()
keyboard.frame = CGRect(x: 0, y: 100, width: 440, height: 100)
keyboard.delegate = self
//复音模式 可以同时按多个键
keyboard.polyphonicMode = true
self.view.addSubview(keyboard)
然后实现代理方法noteon和off
Sample(取样)
位深 bit 一般16位 *6 能96分贝范围的声音
取样率 HZ 一般44100 原频率的两倍 能表现/2 22050 人耳是20-20000hz 根据奈奎斯特的理论,只有采样频率高于声音信号最高频率的两倍时,才能把数字信号表示的声音还原
let bitcrusher = AKBitCrusher(player!)
//位深 一般16位(二进制数) 越低音质越低
bitcrusher.bitDepth = 16
//取样率 HZ 一般44100可以表现/2 22050 人耳是20-20000
bitcrusher.sampleRate = 40000
延迟效果
//延迟时间
delay.time = 0.1
//干湿混合值 1表示只有延迟的被输出
delay.dryWetMix = 1
let leftPan = AKPanner(player, pan: -1)
let rightPan = AKPanner(delay, pan: 1)
let mix = AKMixer(leftPan, rightPan)
AudioKit.output = mix