takaishota
12/25/2015 - 9:57 PM

ヘッドバンギングで音量と再生速度が変わる音楽プレーヤーを作ってみた ref: http://qiita.com/tstnn/items/0fec0ae6fc57858b7a38

ヘッドバンギングで音量と再生速度が変わる音楽プレーヤーを作ってみた 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)