2017-05-29 61 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

我仍然不確定我應該設置帶寬,但我可以在線檢查,或者只是混淆它,直到聲音匹配不同的均衡器應用程序。