[SWIFT] Making a minute repeater part.2

What is a minute repeater?

This is a function installed in ultra-super luxury watches. See last time for details.

https://qiita.com/antk/items/d67d601096161d77f515

Replace the bell sound that was written in print last time with the sound reproduction.

Sound SE

I searched for an mp3 that captured the live sound of a minute repeater as a free sound source, but couldn't find it. I passed this time to play the original sound of mp3, and decided to play something like that with the SE that is included in iOS from the beginning. It may be confusing in terms of usability.

//Use Audio Toolbox
import AudioToolbox

//Determine the sound
let lowGong:SystemSoundID = 1054

//Make a sound
AudioServicesPlaySystemSound(lowGong)

Basically, if you have these three, you can sound the SE built in iOS. By the way, the above 1054 sounds like hitting a glass cup with chopsticks. See the article below to see what types of SEs are available.

** Check iOS system sound ** https://dev.classmethod.jp/articles/ios-systemsound/

For the time being, I decided the sound by listening to all of it in the tedious work of "writing the sound → compiling". Maybe there is a better way.

Implement

Include refactoring based on the advice given in the comments section of the previous article. Adjust by delay processing with reference to the timing when the gong of the actual machine sounds.

import UIKit
import AudioToolbox

class ViewController: UIViewController {
  
  override func viewDidLoad() {
    super.viewDidLoad()
  }
  
  @IBAction func actionButton(_ sender: UIButton) {
    
    let now = Date()
    let time = Calendar.current.dateComponents([.hour, .minute], from: now)
    
    //Round hour to 12 hours
    let hour = time.hour! % 12
    //Number of 60 minutes divided into 15 minutes
    let quarter = time.minute! / 15
    //Fractions less than 15 minutes
    let minute = time.minute! % 15

    //Bass gong
    let lowGong:SystemSoundID = 1054
    //Treble gong
    let highGong:SystemSoundID = 1013
    
    //First gong
    for _ in 0 ..< hour {
      AudioServicesPlaySystemSound(lowGong)
      
      // 0.Wait 5 seconds
      Thread.sleep(forTimeInterval: 0.5)
    }
    
    //Delay processing when the second gong sounds
    if quarter > 0 {
      Thread.sleep(forTimeInterval: 0.7)
    }
    
    //Second gong
    for _ in 0 ..< quarter {
      AudioServicesPlaySystemSound(highGong)
      // 0.Wait 4 seconds
      Thread.sleep(forTimeInterval: 0.4)
      AudioServicesPlaySystemSound(lowGong)
      
      // 0.Wait 5 seconds
      Thread.sleep(forTimeInterval: 0.5)
    }
    
    //Delay processing when the third gong sounds
    if minute > 0 {
      Thread.sleep(forTimeInterval: 0.7)
    }
    
    //Third gong
    for _ in 0 ..< minute {
      print("ding")
      AudioServicesPlaySystemSound(highGong)

      // 0.Wait 5 seconds
      Thread.sleep(forTimeInterval: 0.5)
    }
  }
}

that's all. When I compile it and play it, it sounds like that. However, with this implementation, the process runs every time the button is pressed, so if you hit it repeatedly, the gong will not stop ringing forever. I couldn't find a way to not accept the operation until the processing of @IBAction is completed, so I would be grateful if anyone knows it.

Recommended Posts

Making a minute repeater part.2
Making a minute repeater part.1
Making Frontale a microservice
Make a language! (Making a simple calculator ②)
Precautions when writing a program: Part 3
A little regular expression story Part 2