ヘッドバンギングで音量と再生速度が変わる音楽プレーヤーを作ってみた ref: http://qiita.com/tstnn/items/0fec0ae6fc57858b7a38
var minPitchValue: Float = 0
var maxPitchValue: Float = 0
var count : Int = 1
var pitchValue:Float = 0 {
willSet {
// 曲の開始/一時停止
if pitchValue > 0 && abs(newValue - pitchValue) > 2 && self.audioPlayer?.prepareToPlay() == true {
// 曲が選択されているか、一時停止状態で頭を振ると曲が開始する
self.didStartSwingingHead()
if self.audioPlayer?.playing == false {
self.audioPlayer?.play()
}
} else if self.modalView != nil && abs(newValue - pitchValue) < 0.02 {
// Swingが止まったら、モーダルビューを閉じる
self.modalView!.dismissViewControllerAnimated(true, completion: {self.modalView = nil})
self.audioPlayer?.pause()
self.rateSlider.value = (self.audioPlayer?.rate)!
self.volumeSlider.value = (self.audioPlayer?.volume)!
}
// 音量の変更
if count >= realTimeDataFrequency {
// 1秒間(20Hz)の最大値/最小値から音量を決める(0〜1.0の間で0.125ずつの10段階)
if self.audioPlayer != nil {
self.audioPlayer!.volume = ceilf(((abs(sin(self.minPitchValue * Float(M_PI/180))) + abs(sin(self.maxPitchValue * Float(M_PI/180)))) * 0.5)/volumeUnit) * volumeUnit
// print(NSString(format: "Volume: %0.3f", self.audioPlayer!.volume))
self.maxPitchValue = 0
self.minPitchValue = 0
count = 1
}
}
if newValue > self.maxPitchValue {
self.maxPitchValue = newValue
} else if newValue < self.minPitchValue {
self.minPitchValue = newValue
}
count += 1
}
}
var dRate: Float = 0.1
var signChangeCount: Int = 0
var newSignChangeCount: Int = 0
var accYValue: Int8 = 0 {
willSet {
// 1秒間(20Hz)の上下往復の頻度を計測する
if count >= realTimeDataFrequency {
if self.audioPlayer != nil {
// 往復頻度(加速度 > 0 <-> 加速度 < 0 への切り替わり回数)が増えていたら再生速度を早くする
if newSignChangeCount > signChangeCount {
self.audioPlayer?.rate += dRate * Float(newSignChangeCount - signChangeCount)
} else if newSignChangeCount < signChangeCount {
self.audioPlayer?.rate -= dRate * Float(signChangeCount - newSignChangeCount)
}
// print(NSString(format: "Rate: %0.3f", self.audioPlayer!.rate))
signChangeCount = newSignChangeCount
newSignChangeCount = 0
}
}
if isPlus(newValue) != isPlus(accYValue) {
newSignChangeCount += 1
}
}
}
func isPlus(value : Int8) -> Bool {
var r: Bool
if value > 0 {
r = true
} else {
r = false
}
return r
}
func memeRealTimeModeDataReceivedPitch(dataPitch: Float) {
// 角度に応じて顔の位置を上下に動かす(角度:-90〜90度ぐらい 最大20pt)
let d: Float = 20
self.swingingHead.center.y = self.view.center.y + CGFloat(d * sin(dataPitch * Float(M_PI/180)))
}
var audioPlayer: AVAudioPlayer?
audioPlayer = try? AVAudioPlayer(contentsOfURL: url)
player.enableRate = true
player.rate = 2.0 // 0〜2.0
player.volume = 1.0 // 0〜1.0
player.play()
player.pause()
player.stop()
self.audioPlayer!.volume = ceilf(
((abs(sin(self.minPitchValue * Float(M_PI/180))) + abs(sin(self.maxPitchValue * Float(M_PI/180)))) * 0.5)/volumeUnit
) * volumeUnit
self.audioPlayer?.rate += dRate * Float(newSignChangeCount - signChangeCount)