如何正確創建AVAudioUnitSampler的音量信封?AVAudioUnitSampler AVFoundation的正確音量信封
基本上我想添加一個攻擊階段,其中的卷在幾毫秒內消失以避免點擊。另外,我想添加一個發佈階段,以便在停止播放音符後音量消失。
我做了什麼至今:
我成立了一個代表我的採樣率一個全球性的定時器。 爲此,我使用了一個間隔長度爲1個樣本的NSTimer(對於樣本率爲44100,一個樣本時間長度爲1/44100)。這樣一個人不應該聽到音量「跳躍」導致「點擊」。也許我需要過採樣兩倍的採樣率。
只要增益低於某個閾值,定時器就會調用增加masterGain的函數。通過將期望和當前增益的差值除以採樣率,然後將該值除以所需的衰減時間,計算出我增加的量。 (在下面的示例中,我使用固定值進行簡單讀取)
達到閾值後,移除計時器並停止筆記。
- >我認爲這種方法非常複雜,特別是當我使用釋放階段時。
請檢查我的示例代碼。我用UIButton touchDown來觸發播放的音符。請告訴我,如果你知道一個更簡單的方法來隨時間自動化一個值/建立一個淡入/淡出的體積。
感謝
import UIKit
import AVFoundation
class ViewController: UIViewController {
var engine: AVAudioEngine!
var sampler: AVAudioUnitSampler!
var error: NSError?
var timer: NSTimer = NSTimer()
override func viewDidLoad() {
super.viewDidLoad()
engine = AVAudioEngine()
sampler = AVAudioUnitSampler()
engine.attachNode(sampler)
engine.connect(sampler, to: engine.mainMixerNode, format: nil)
if !engine!.startAndReturnError(&error) {
if let error = error {
println("Engine could not start!")
println(error.localizedDescription)
}
}
}
@IBAction func touchDown(sender: UIButton, forEvent event: UIEvent) {
sampler.startNote(66, withVelocity: 66, onChannel: 0)
sampler.masterGain = -90
timer = NSTimer.scheduledTimerWithTimeInterval (1/44100, target: self, selector: "updateVolume", userInfo: nil, repeats: true)
}
func updateVolume() {
if sampler.masterGain <= -10 {
sampler.masterGain = sampler.masterGain + 0.1
println("volume updated")
} else {
timer.invalidate()
}
}
}
你好PicnicTripper!感謝你的回答。你有什麼指導如何在iOS中做到這一點?據我瞭解你的方法 - >你將文件的每個樣本乘以介於0和1之間的函數的幅度。音頻框架的文檔不是iOS中最好的。所以我總是歡迎進一步的輸入:) –
嗨Tobias!這正是你如何將振幅包絡應用於聲音的問題。難道我不是iOS開發人員,但我可能會提供幫助。如果您希望實時執行此操作,也許可以在此處爲代碼添加另一圖層; engine.attachNode(採樣) engine.connect(採樣,以:engine.mainMixerNode,格式:無) 這將有可能到採樣器連接到這可能需要輸入幅度,並通過它們相乘處理部分的幅度包絡?如果你有一個幅度值流進來,你可以在那裏執行你的幅度包絡函數? – PicnicTripper
是的,有一種方法可以在iOS中使用Audiobuffer對象。我需要檢查我可以用取樣器的輸出填充Audiobuffers,然後在按下的每個按鈕上重新啓動信封文件。不幸的是,Audiobuffer Classes不易掌握......我會在此更新任何進度。 –