javaSEがiOSアプリデザイン、開発に挑む日記

本業java SEがswift、デザインの勉強したことを残しておくブログ

swiftで音源打ち込み再生、ブツッと切れない

swiftで 、コードをセットしたら自動でソロしてくれるアプリ欲しいなぁと思って、

第一段階として

指定秒数、指定順序で再生して、音がブツッと切れないソースを記述

class ViewController: UIViewController {

    class SoundNode{
        var sound : AVAudioPlayer
        var initLen : Float
        var isStop = false
        
        init(sound:AVAudioPlayer, initLen:Float){
            self.sound = sound
            self.initLen = initLen
            self.sound.volume = 0.4
        }
    }
    
    var playList:Array = []
    
    var pianoSound1C = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("1C", ofType: "mp3")!)
    var curNodeId = 0
    

    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func playMusic(sender: UIButton) {
        var avp1 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        var avp2 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        var avp3 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        var avp4 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        var avp5 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        var avp6 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        var avp7 = AVAudioPlayer(contentsOfURL: pianoSound1C, error: nil)
        
        avp1.prepareToPlay()
        avp2.prepareToPlay()
        avp3.prepareToPlay()
        avp4.prepareToPlay()
        avp5.prepareToPlay()
        avp6.prepareToPlay()
        avp7.prepareToPlay()
        
        
        var node = SoundNode(sound: avp1, initLen: 2.0)
        var node2 = SoundNode(sound: avp2, initLen: 1.0)
        var node3 = SoundNode(sound: avp3, initLen: 1.0)
        var node4 = SoundNode(sound: avp4, initLen: 0.666)
        var node5 = SoundNode(sound: avp5, initLen: 0.334)
        var node6 = SoundNode(sound: avp6, initLen: 0.666)
        var node7 = SoundNode(sound: avp7 , initLen: 0.334)
        
        playList.append(node)
        playList.append(node2)
        playList.append(node3)
        playList.append(node4)
        playList.append(node5)
        playList.append(node6)
        playList.append(node7)
        
        playNode()
        
    }
    
    func playNode(){
        NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("loopNode:"), userInfo: nil, repeats: true)
        
    }
    

    func loopNode(timer: NSTimer){
        if curNodeId < playList.count {
            if curNodeId == 0 {
                var tmpNode = playList[curNodeId]
                tmpNode.sound.play()
                NSTimer.scheduledTimerWithTimeInterval(Double(tmpNode.initLen), target: self, selector: Selector("stopNode:"), userInfo: curNodeId, repeats: false)
                curNodeId++
            }else{
                var prevNode = playList[curNodeId-1]
                if(prevNode.isStop){
                    var tmpNode = playList[curNodeId]
                    tmpNode.sound.play()
                    NSTimer.scheduledTimerWithTimeInterval(Double(tmpNode.initLen), target: self, selector: Selector("stopNode:"), userInfo: curNodeId, repeats: false)
                    curNodeId++
                }else{
                    
                }
                
            }
        }else{
            timer.invalidate()
        }
        
    }

    
    func stopNode(timer: NSTimer){
        let nodeId = timer.userInfo as! Int
        var tmpNode = playList[nodeId]
        tmpNode.isStop = true
        
        NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("fadeout:"), userInfo: nodeId, repeats: true)
    }
    
    
    func fadeout(timer: NSTimer){
        let nodeId = timer.userInfo as! Int
        var tmpNode = playList[nodeId]
        if tmpNode.sound.volume <= 0.0{
            tmpNode.sound.stop()
            tmpNode.sound.volume = 0.4
            tmpNode.sound.currentTime = 0
            timer.invalidate()
        }else{
            tmpNode.sound.volume = tmpNode.sound.volume - 0.02
        }
    }
    

    
    
}

 

 NSTimerの秒数はもっと精査する必要があるのかなと。

あと、もっといいやり方、ライブラルがありそうな気配は感じたり...

 

 良ければご参考にどうぞ。