2017-05-29 62 views
3

我想用AVAudioEngine制作一个5段音频均衡器(60Hz,230Hz,910Hz,4kHz,14kHz)。我希望通过垂直滑块使用户输入每个频段的增益,并相应地调整正在播放的音频。我尝试使用AVAudioUnitEQ来做到这一点,但播放音频时我听到没有什么区别。我试图在值中硬编码来指定每个频率的增益,但它仍然不起作用。这里是我的代码:构建一个简单的均衡器

var audioEngine: AVAudioEngine = AVAudioEngine() 
var equalizer: AVAudioUnitEQ! 
var audioPlayerNode: AVAudioPlayerNode = AVAudioPlayerNode() 
var audioFile: AVAudioFile! 

// in viewDidLoad(): 
equalizer = AVAudioUnitEQ(numberOfBands: 5) 
audioEngine.attach(audioPlayerNode) 
audioEngine.attach(equalizer) 
let bands = equalizer.bands 
let freqs = [60, 230, 910, 4000, 14000] 
audioEngine.connect(audioPlayerNode, to: equalizer, format: nil) 
audioEngine.connect(equalizer, to: audioEngine.outputNode, format: nil) 
for i in 0...(bands.count - 1) { 
    bands[i].frequency = Float(freqs[i]) 
} 

bands[0].gain = -10.0 
bands[0].filterType = .lowShelf 
bands[1].gain = -10.0 
bands[1].filterType = .lowShelf 
bands[2].gain = -10.0 
bands[2].filterType = .lowShelf 
bands[3].gain = 10.0 
bands[3].filterType = .highShelf 
bands[4].gain = 10.0 
bands[4].filterType = .highShelf 

do { 
    if let filepath = Bundle.main.path(forResource: "song", ofType: "mp3") { 
     let filepathURL = NSURL.fileURL(withPath: filepath) 
     audioFile = try AVAudioFile(forReading: filepathURL) 
     audioEngine.prepare() 
     try audioEngine.start() 
     audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: nil) 
     audioPlayerNode.play() 
    } 
} catch _ {} 

由于低频有-10的增益和高频具有10倍增益,播放任何媒体的时候应该有一个非常显着的差异。但是,当媒体开始播放时,听起来就像没有附加均衡器一样播放。

我不知道为什么会发生这种情况,但我尝试了几个不同的事情来调试。我认为这可能是函数的顺序,所以我尝试切换它,以便调整所有band后调用audioEngine.connect,但这也没有什么不同。

我尝试使用AVAudioUnitTimePitch这个相同的代码,它的工作完美,所以我傻眼了为什么它不起作用AVAudioUnitEQ

我不想为这个项目使用任何第三方库或可可豆荚,我想单独使用AVFoundation

任何帮助将不胜感激!

在此先感谢。

回答

4

AVAudioUnitEQFilterParameters AVAudioUnitEQFilterParameters Documentation 通过文档看,我注意到,我曾与所有除bypass参数的混乱,似乎改变这个标志固定的一切!

因此,我认为这里的主要问题是每个AVAudioUnitEQ频段不能被提供的系统值绕过,而不是程序员设置的值。

于是,我改变

for i in 0...(bands.count - 1) { 
    bands[i].frequency = Float(freqs[i]) 
} 

for i in 0...(bands.count - 1) { 
    bands[i].frequency = Float(freqs[i]) 
    bands[i].bypass  = false 
    bands[i].filtertype = .parametric 
} 

,一切都开始工作。此外,为了制作允许用户修改单个频率的有效均衡器,每个频段的filtertype应设置为.parametric

我仍然不确定我应该设置带宽,但我可以在线检查,或者只是混淆它,直到声音匹配不同的均衡器应用程序。