2017-05-29 27 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のゲインを持っているので、任意のメディアを再生する際に、非常に顕著な違いがあるはずです。ただし、メディアの再生が開始されると、イコライザが接続されていない状態で再生された場合と同じように再生されます。

なぜこれが起こっているのか分かりませんが、デバッグするにはいくつかのことを試しました。私はそれが関数の順番かもしれないと思ったので、audioEngine.connectがすべてのバンドを調整した後に呼び出されるように切り換えようとしましたが、違いはありませんでした。

AVAudioUnitTimePitchを使用してこの同じコードを試してみましたが、それは完全に機能していたので、なぜそれがAVAudioUnitEQと一緒に動作しないのかと唖然としています。

私はこのプロジェクトにサードパーティのライブラリやココアポッドを使用したくないので、AVFoundationだけを使ってやりたいと思います。

ご協力いただければ幸いです!

ありがとうございます。ドキュメントを通じて探し

答えて

4

AVAudioUnitEQFilterParameters AVAudioUnitEQFilterParameters Documentation 、私はbypassを除くすべてのパラメータとめちゃめちゃていたことに気付き、このフラグを変更すると、すべてを固定しているようです!

ここでの主な問題は、各AVAudioUnitEQバンドが、プログラマが設定する値ではなく、提供されたシステム値でバイパスしてはならないということです。

だから、私は

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

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

を変更し、すべてが仕事を始めました。さらに、ユーザーが個々の周波数を変更できるようにする効果的なイコライザーを作成するには、各バンドのfiltertype.parametricに設定する必要があります。

帯域幅を設定する必要があるかどうかはまだ分かりませんが、サウンドが別のイコライザアプリケーションと一致するまでオンラインでチェックしたり、混乱させたりすることがあります。

関連する問題