       toneDirs = try FM.contentsOfDirectory(atPath: "\(Bundle.main.resourcePath!)/tones")
     }
     catch {
-        // do nothing
-        NSLog("Cannot load toneDirs !")
+      // do nothing
+      NSLog("Cannot load toneDirs !")
     }
     
     // Estimote Beacon

    // playerPoints
    for i in 0..<SLIT_COUNT {
      playerPoints += [360.0/Double(SLIT_COUNT)*Double(i)]
    }
    
    
    // load settings
    // =============
    
    let uuid = UIDevice.current.identifierForVendor!.uuidString
    NSLog("uuid:\(uuid)")
    uuidLabel.text = "uuid:\(uuid)"
    
    let device: NSMutableDictionary
    if devices[uuid] != nil {
      device = devices[uuid] as! NSMutableDictionary
    }
    else {
      NSLog("Not found device configuration")
      device = devices[devices.allKeys.first!] as! NSMutableDictionary
    }
    
    if let konashi = device.value(forKey: "konashi") as? String {
      konashiBtnDefaultLabel = "Find Konashi (\(konashi))"
      konashiBtn.setTitle(konashiBtnDefaultLabel, for: UIControlState())
    }
    
    
    
    // Sound
    
    // Delay
    delay = AVAudioUnitDelay()
    setDelayWetDry(0) // 可変 0-80
    setDelayDelayTime(0.295) // 不変
    setDelayFeedback(0) // 可変 0-90
    setDelayLowPassCutOff(700) // 不変
    
    setBrightnessMin(0.15)
    
    mixer = AVAudioMixerNode()
    
    engine.attach(delay)
    engine.attach(mixer)
    
    // AudioPlayerの準備
    // OneShot
    var toneDir: String = toneDirs.first!
    toneDir = (device.value(forKey: "tone") as! String) ?? toneDirs.first! // 先に_default["tone"]のを代入試み、なかったらtoneDirs.first
    
    let format: AVAudioFormat = initPlayers(toneDir as String)

    engine.connect(mixer, to: delay, format: format)
    engine.connect(delay, to: engine.mainMixerNode, format: format)
    do {
      try engine.start()
    }
    catch {
      NSLog("AVAudioEngine start error")
    }
    
    // モーションセンサー
    if MM.isDeviceMotionAvailable {
      MM.deviceMotionUpdateInterval = MM_UPDATE_INTERVAL
      MM.startDeviceMotionUpdates(to: OperationQueue()) { deviceMotion, error in
        let rotation = atan2(deviceMotion!.gravity.x, deviceMotion!.gravity.y) - .pi
        self.updateRotation(rotation)
      }
    }
    
    // Color
    loadInstrumentColor(toneDir as NSString)
    
    hueSlider2.setValue(0.66, animated: true)
    saturationSlider2.setValue(1.0, animated: true)
    
    divideSlider.setValue(Float(UD.integer(forKey: UD_KEY_LED_DIVIDE)), animated: true)
    changeDivide(divideSlider)
    
    positionSlider.setValue(Float(UD.integer(forKey: UD_KEY_LED_POSITION)), animated: true)
    changePosition(positionSlider)
    
    sendInstrumentColor()
    sendEffectColor()
    setBrightnessMin(self.brightnessSlider.value)
    
    // Konashi関係
    logKonashiStatus()
    
    Konashi.shared().connectedHandler = {
      NSLog("[Konashi] Connected!")
    }
    Konashi.shared().disconnectedHandler = {
      NSLog("[Konashi] Disconnected")
      
      // button
      self.konashiBtn.setTitle(self.konashiBtnDefaultLabel, for: [])
      
//      // 勝手に切断された場合にリトライする
//      if self.manualDisconnection == false {
//        // UserDefaultsから前回接続したKonashiを読み、接続を試みる
//        if let previously_connected_konashi = self.UD.stringForKey(self.UD_KEY_KONASHI) {
//          NSLog("[Konashi] Retry connecting to \(previously_connected_konashi) (previus connection) ...")
//          self.findKonashiWithName(previously_connected_konashi)
//        }
//      }
//      self.manualDisconnection = false
    }
    Konashi.shared().readyHandler = {
      NSLog("[Konashi] Ready...")
      
      // stop timer
      if self.connectionCheckTimer != nil && self.connectionCheckTimer.isValid {
        NSLog("[Konashi] Stop connection check")
        self.connectionCheckTimer.invalidate()
      }
      
      self.logKonashiStatus()
      
      let konashiName = Konashi.peripheralName()
      
      self.UD.set(konashiName, forKey: self.UD_KEY_KONASHI)
      
      
      // button
      self.konashiBtn.setTitle("[Connected] \(konashiName)", for: [])
      
      // Konashi setting
      Konashi.uartMode(KonashiUartMode.enable, baudrate: KonashiUartBaudrate.rate9K6)
      Konashi.pinMode(KonashiDigitalIOPin.digitalIO1, mode: KonashiPinMode.output)
      
      // LED2を点灯
      Konashi.digitalWrite(KonashiDigitalIOPin.digitalIO1, value: KonashiLevel.high)
      
      self.sendPlayerType()
      self.sendEffectColor()
      self.sendInstrumentColor()
      self.setBrightnessMin(self.brightnessSlider.value)
    }
//    Konashi.shared().uartRxCompleteHandler = {(data: NSData!) -> Void in
//      NSLog("[Konashi] UartRx \(data.description)")
//    }
    
    if let default_konashi = device.value(forKey: "konashi") as? String {
      NSLog("[Konashi] Auto connecting to \(default_konashi) (default) ...")
      findKonashiWithName(default_konashi)
    }
  }
  

  override func viewDidLoad() {
    super.viewDidLoad()
    
    initialize()
    
    // load settings
    // =============
    
    let uuid = UIDevice.current.identifierForVendor!.uuidString
    NSLog("uuid:\(uuid)")
    uuidLabel.text = "uuid:\(uuid)"
    
    let device: NSMutableDictionary
    if devices[uuid] != nil {
      device = devices[uuid] as! NSMutableDictionary
    }
    else {
      NSLog("Not found device configuration")
      device = devices[devices.allKeys.first!] as! NSMutableDictionary
    }
    
    if let konashi = device.value(forKey: "konashi") as? String {
      konashiBtnDefaultLabel = "Find Konashi (\(konashi))"
      konashiBtn.setTitle(konashiBtnDefaultLabel, for: UIControlState())
    }
    
    
    
    // Sound
    
    // Delay
    delay = AVAudioUnitDelay()
    setDelayWetDry(0) // 可変 0-80
    setDelayDelayTime(0.295) // 不変
    setDelayFeedback(0) // 可変 0-90
    setDelayLowPassCutOff(700) // 不変
    
    setBrightnessMin(0.15)
    
    mixer = AVAudioMixerNode()
    
    engine.attach(delay)
    engine.attach(mixer)
    
    // AudioPlayerの準備
    // OneShot
    var toneDir: String = toneDirs.first!
    toneDir = (device.value(forKey: "tone") as! String) ?? toneDirs.first! // 先に_default["tone"]のを代入試み、なかったらtoneDirs.first
    
    let format: AVAudioFormat = initPlayers(toneDir as String)

    engine.connect(mixer, to: delay, format: format)
    engine.connect(delay, to: engine.mainMixerNode, format: format)
    do {
      try engine.start()
    }
    catch {
      NSLog("AVAudioEngine start error")
    }
    
    // モーションセンサー
    if MM.isDeviceMotionAvailable {
      MM.deviceMotionUpdateInterval = MM_UPDATE_INTERVAL
      MM.startDeviceMotionUpdates(to: OperationQueue()) { deviceMotion, error in
        let rotation = atan2(deviceMotion!.gravity.x, deviceMotion!.gravity.y) - .pi
        self.updateRotation(rotation)
      }
    }
    
    // Color
    loadInstrumentColor(toneDir as NSString)
    
    hueSlider2.setValue(0.66, animated: true)
    saturationSlider2.setValue(1.0, animated: true)
    
    divideSlider.setValue(Float(UD.integer(forKey: UD_KEY_LED_DIVIDE)), animated: true)
    changeDivide(divideSlider)
    
    positionSlider.setValue(Float(UD.integer(forKey: UD_KEY_LED_POSITION)), animated: true)
    changePosition(positionSlider)
    
    sendInstrumentColor()
    sendEffectColor()
    setBrightnessMin(self.brightnessSlider.value)
    
    // Konashi関係
    logKonashiStatus()
    
    Konashi.shared().connectedHandler = {
      NSLog("[Konashi] Connected!")
    }
    Konashi.shared().disconnectedHandler = {
      NSLog("[Konashi] Disconnected")
      
      // button
      self.konashiBtn.setTitle(self.konashiBtnDefaultLabel, for: [])
      
//      // 勝手に切断された場合にリトライする
//      if self.manualDisconnection == false {
//        // UserDefaultsから前回接続したKonashiを読み、接続を試みる
//        if let previously_connected_konashi = self.UD.stringForKey(self.UD_KEY_KONASHI) {
//          NSLog("[Konashi] Retry connecting to \(previously_connected_konashi) (previus connection) ...")
//          self.findKonashiWithName(previously_connected_konashi)
//        }
//      }
//      self.manualDisconnection = false
    }
    Konashi.shared().readyHandler = {
      NSLog("[Konashi] Ready...")
      
      // stop timer
      if self.connectionCheckTimer != nil && self.connectionCheckTimer.isValid {
        NSLog("[Konashi] Stop connection check")
        self.connectionCheckTimer.invalidate()
      }
      
      self.logKonashiStatus()
      
      let konashiName = Konashi.peripheralName()
      
      self.UD.set(konashiName, forKey: self.UD_KEY_KONASHI)
      
      
      // button
      self.konashiBtn.setTitle("[Connected] \(konashiName)", for: [])
      
      // Konashi setting
      Konashi.uartMode(KonashiUartMode.enable, baudrate: KonashiUartBaudrate.rate9K6)
      Konashi.pinMode(KonashiDigitalIOPin.digitalIO1, mode: KonashiPinMode.output)
      
      // LED2を点灯
      Konashi.digitalWrite(KonashiDigitalIOPin.digitalIO1, value: KonashiLevel.high)
      
      self.sendPlayerType()
      self.sendEffectColor()
      self.sendInstrumentColor()
      self.setBrightnessMin(self.brightnessSlider.value)
    }
//    Konashi.shared().uartRxCompleteHandler = {(data: NSData!) -> Void in
//      NSLog("[Konashi] UartRx \(data.description)")
//    }
    
    if let default_konashi = device.value(forKey: "konashi") as? String {
      NSLog("[Konashi] Auto connecting to \(default_konashi) (default) ...")
      findKonashiWithName(default_konashi)
    }
  }
  
  func initialize() {
    
    // "{IPHONE-UUIDString}":["tone":"{TONE-NAME}","konashi":"{KONASHI-ID}",["color":["hue":{val},"saturation":{val}]]]
    // [注意] defaults = [["DAE4E972-9F4D-4EDB-B511-019B0214944F":["tone":"A-L"],..],...] みたいな書き方をするとindexingが止まらなくなる 参考：http://qiita.com/osamu1203/items/270fc716883d86d8f3b7
