使用 Swift 使用 AVAudioEngine 实时进行音高转换
Posted
技术标签:
【中文标题】使用 Swift 使用 AVAudioEngine 实时进行音高转换【英文标题】:Pitch Shifting in Real Time With AVAudioEngine using Swift 【发布时间】:2015-11-24 12:36:11 【问题描述】:我正在使用 Swift 在 OSX 上开发音频效果应用程序,我对集成音高变换效果很感兴趣。
我想实时将音调上调或下调一个八度。目前我只收到一个干燥的信号。
我不确定这是否可能,我想知道这是否可能,或者任何人可能有任何帮助或建议。
目前与问题相关的代码如下:
import Cocoa
import AVFoundation
class ViewController: NSViewController
var engine = AVAudioEngine()
var timePitch = AVAudioUnitTimePitch()
override func viewDidLoad()
timePitch.pitch = 1200
// Setup engine and node instances
var mixer = engine.mainMixerNode
var input = engine.inputNode
var output = engine.outputNode
var format = input.inputFormatForBus(0)
var error:NSError?
engine.attachNode(timePitch)
engine.connect(input, to: timePitch, format: format)
engine.connect(timePitch, to: output, format: format)
engine.startAndReturnError(&error)
super.viewDidLoad()
override var representedObject: AnyObject?
didSet
// Update the view, if already loaded.
【问题讨论】:
【参考方案1】:timePitch.pitch = -500 //Rude man voice
timePitch.rate = 1.5 //In 1.5 times faster
检查this tutorial。和direct link 以获取更多信息的教程示例。
Swift 2.0 示例:
import UIKit
import AVFoundation
class ViewController: UIViewController
var engine: AVAudioEngine!
var player: AVAudioPlayerNode!
var file = AVAudioFile()
override func viewDidLoad()
super.viewDidLoad()
engine = AVAudioEngine()
player = AVAudioPlayerNode()
player.volume = 1.0
let path = NSBundle.mainBundle().pathForResource("in", ofType: "caf")!
let url = NSURL.fileURLWithPath(path)
let file = try? AVAudioFile(forReading: url)
let buffer = AVAudioPCMBuffer(PCMFormat: file!.processingFormat, frameCapacity: AVAudioFrameCount(file!.length))
do
try file!.readIntoBuffer(buffer)
catch _
let pitch = AVAudioUnitTimePitch()
//
pitch.pitch = -500 //Distortion
pitch.rate = 1.5 //Voice speed
//
engine.attachNode(player)
engine.attachNode(pitch)
engine.connect(player, to: pitch, format: buffer.format)
engine.connect(pitch, to: engine.mainMixerNode, format: buffer.format)
player.scheduleBuffer(buffer, atTime: nil, options: AVAudioPlayerNodeBufferOptions.Loops, completionHandler: nil)
engine.prepare()
do
try engine.start()
catch _
player.play()
【讨论】:
非常感谢分享。 更改 pitch.rate 时的质量。有什么方法可以在费率变化时保持相同的质量【参考方案2】:timePitch.pitch = 1000 //Filtered Voice
timePitch.rate = 1 //Normal rate
【讨论】:
虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高答案的长期价值。 感谢您的建议@唐老鸭。下次我会记住这一点以上是关于使用 Swift 使用 AVAudioEngine 实时进行音高转换的主要内容,如果未能解决你的问题,请参考以下文章
AVAudioEngine MIDI 文件播放(当前进度+MIDI 结束回调)Swift
Swift AVAudioEngine - 如何使本地麦克风静音