我想建立一個可靠的固態系統中使用SWIFT在我的應用程序建立一個節拍器。斯威夫特固體節拍器系統
我已經建立了使用NSTimer到目前爲止似乎是一個堅實的系統..我現在唯一的問題是當計時器開始第2次點擊是關閉時間,但隨後它捕捉到一個堅實的時間表。
現在我所有的研究後,我看到有人提到你應該使用其他音頻工具,不是靠的NSTimer ..或者,如果你選擇使用的NSTimer那麼就應該是在自己的線程。現在我看到很多人對此感到困惑,包括我自己,我很想深入這個節拍器業務的底部,並解決這個問題並與所有正在掙扎的人分享。
UPDATE
所以我已經實現,並在反饋我最後一次收到後,這一點清理。這裏是我的代碼的結構。它的播放。但我仍然得到一開始2次快速點擊,然後它在定居。
我對我的無知這一個道歉。我希望我走在正確的道路上。
我目前原型的另一種方法爲好。在哪裏我有一個非常小的音頻文件,只需點擊一下,死循環結束,並持續正確的持續時間,直到獲得特定節奏的循環點。我正在循環使用,效果很好。但唯一的事情是我沒有得到檢測迴路點視覺更新,所以我有我的基本的NSTimer只是檢測正在處理的音頻下的定時間隔,它似乎對決非常好整個無延遲。但我仍然寧願用這個NSTimer來得到它。如果您可以輕易發現我的錯誤,那麼我們可以在正確的方向上再踢一次,我相信它很快就會有效!非常感謝。
//VARIABLES
//AUDIO
var clickPlayer:AVAudioPlayer = AVAudioPlayer()
let soundFileClick = NSBundle.mainBundle().pathForResource("metronomeClick", ofType: ".mp3")
//TIMERS
var metroTimer = NSTimer()
var nextTimer = NSTimer()
var previousClick = CFAbsoluteTimeGetCurrent() //When Metro Starts Last Click
//Metro Features
var isOn = false
var bpm = 60.0 //Tempo Used for beeps, calculated into time value
var barNoteValue = 4 //How Many Notes Per Bar (Set To Amount Of Hits Per Pattern)
var noteInBar = 0 //What Note You Are On In Bar
//********* FUNCTIONS ***********
func startMetro()
{
MetronomeCount()
barNoteValue = 4 // How Many Notes Per Bar (Set To Amount Of Hits Per Pattern)
noteInBar = 0 // What Note You Are On In Bar
isOn = true //
}
//Main Metro Pulse Timer
func MetronomeCount()
{
previousClick = CFAbsoluteTimeGetCurrent()
metroTimer = NSTimer.scheduledTimerWithTimeInterval(60.0/bpm, target: self, selector: Selector ("MetroClick"), userInfo: nil, repeats: true)
nextTimer = NSTimer(timeInterval: (60.0/Double(bpm)) * 0.01, target: self, selector: "tick:", userInfo: ["bpm":bpm], repeats: true)
}
func MetroClick()
{
tick(nextTimer)
}
func tick(timer:NSTimer)
{
let elapsedTime:CFAbsoluteTime = CFAbsoluteTimeGetCurrent() - previousClick
let targetTime:Double = 60/timer.userInfo!.objectForKey("bpm")!.doubleValue!
if (elapsedTime > targetTime) || (abs(elapsedTime - targetTime) < 0.003)
{
previousClick = CFAbsoluteTimeGetCurrent()
//Play the click here
if noteInBar == barNoteValue
{
clickPlayer.play() //Play Sound
noteInBar = 1
}
else//If We Are Still On Same Bar
{
clickPlayer.play() //Play Sound
noteInBar++ //Increase Note Value
}
countLabel.text = String(noteInBar) //Update UI Display To Show Note We Are At
}
}
感謝您的創意。我很欣賞詳細的反饋。我會研究這一點,看看我能從這個建議中得出什麼。會及時向大家發佈。 – CakeGamesStudios
嗯...所以我看着這似乎我被卡住....我已經設置它,並存儲我現在的時間點擊使用CFAbsoluteTime它將存儲時間就好了,但每次我存儲一個新的值來比較它也是通過當前時間進行的,所以總是有一個偏移量被加到存儲的時間上,用來比較前一次和當前時間以獲得我的容忍度。我花了相當長的時間試圖讓這個工作。我也仔細看過了這個例子,但仍然不清楚該怎麼做。任何進一步的解釋將不勝感激。謝謝! – CakeGamesStudios
你能用CFAbsoluteTime發佈你的更新代碼嗎? – vigneshv