Swift Solid Metronome System

前端 未结 3 496
北恋
北恋 2020-12-28 23:30

I am trying to build a reliable solid system to build a metronome in my app using SWIFT.

I Have built what seems to be a solid system using NSTimer so far.. The only

3条回答
  •  甜味超标
    2020-12-29 00:12

    Ok! You can't get things right basing on time, because somehow we need to deal with DA converters and their frequency - samplerate. We need to tell them the exact sample to start play the sound. Add a single view iOS app with two buttons start and stop and insert this code into ViewController.swift. I keep things simple and it's just an Idea of how we can do this. Sorry for forcing try... This one is made with swift 3. Also check out my project on GitHub https://github.com/AlexShubin/MetronomeIdea

    Swift 3

       import UIKit
        import AVFoundation
    
        class Metronome {
    
            var audioPlayerNode:AVAudioPlayerNode
            var audioFile:AVAudioFile
            var audioEngine:AVAudioEngine
    
            init (fileURL: URL) {
    
                audioFile = try! AVAudioFile(forReading: fileURL)
    
                audioPlayerNode = AVAudioPlayerNode()
    
                audioEngine = AVAudioEngine()
                audioEngine.attach(self.audioPlayerNode)
    
                audioEngine.connect(audioPlayerNode, to: audioEngine.mainMixerNode, format: audioFile.processingFormat)
                try! audioEngine.start()
    
            }
    
            func generateBuffer(forBpm bpm: Int) -> AVAudioPCMBuffer {
                audioFile.framePosition = 0
                let periodLength = AVAudioFrameCount(audioFile.processingFormat.sampleRate * 60 / Double(bpm))
                let buffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat, frameCapacity: periodLength)
                try! audioFile.read(into: buffer)
                buffer.frameLength = periodLength
                return buffer
            }
    
            func play(bpm: Int) {
    
                let buffer = generateBuffer(forBpm: bpm)
    
       self.audioPlayerNode.play()
    
                self.audioPlayerNode.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)
    
    
    
            }
    
            func stop() {
    
                audioPlayerNode.stop()
    
            }
    
        }
    
    
        class ViewController: UIViewController {
    
            var metronome:Metronome
    
            required init?(coder aDecoder: NSCoder) {
    
                let fileUrl = Bundle.main.url(forResource: "Click", withExtension: "wav")
    
                metronome = Metronome(fileURL: fileUrl!)
    
                super.init(coder: aDecoder)
    
            }
    
            @IBAction func StartPlayback(_ sender: Any) {
    
                metronome.play(bpm: 120)
    
            }
    
            @IBAction func StopPlayback(_ sender: Any) {
    
                metronome.stop()
    
            }
    
        }
    

提交回复
热议问题