Звук воспроизводится только в первый раз с использованием AVAudioEngine в iOS

У меня есть звуковой файл, который прослушивается как звуковой сигнал, и мне приходится многократно воспроизводить этот звук с изменением его высоты в зависимости от некоторых условий. Я использую AVAudioEngine, AVAudioPlayerNode и AVAudioUnitTimePitch для достижения этой цели. На мой взгляд, есть две кнопки, а именно Воспроизвести и Стоп. Когда я нажимаю кнопку «Воспроизвести» в первый раз, звук воспроизводится повторно, но после однократного нажатия на кнопку «Стоп» и повторного нажатия на кнопку «Воспроизведение» звук не воспроизводится и не выдает никаких ошибок. Я долго искал эту проблему, но не мог найти решение, и я пришел сюда. Не могли бы вы помочь мне решить эту проблему. Или есть другие альтернативные решения моей проблемы? Мой код выглядит следующим образом:

import UIKit
import AVFoundation

class ViewController: UIViewController {

    let engine = AVAudioEngine()
    let audioPlayer = AVAudioPlayerNode()
    let pitchUnit = AVAudioUnitTimePitch()

    var avAudioFile: AVAudioFile!

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

        let path = Bundle.main.path(forResource: "Beep", ofType: "wav")!
        let url = NSURL.init(fileURLWithPath: path)
        avAudioFile = try? AVAudioFile(forReading: url as URL)

        setup()
    }

    func setup() {
        engine.attach(audioPlayer)
        engine.attach(pitchUnit)
        engine.connect(audioPlayer, to: pitchUnit, format: nil)
        engine.connect(pitchUnit, to:engine.mainMixerNode, format: nil)

        try? engine.start()

        audioPlayer.volume = 1.0
        audioPlayer.play()

    }
    @IBAction func playSound(_ sender: UIButton) {

        pitchUnit.pitch = 1

        // interrupt playing sound if you have to
        if audioPlayer.isPlaying {
            audioPlayer.stop()
            audioPlayer.play()
        }
        let buffer = AVAudioPCMBuffer(pcmFormat: avAudioFile.processingFormat, frameCapacity: AVAudioFrameCount(avAudioFile.length))
        try? avAudioFile.read(into: buffer!)
        audioPlayer.scheduleBuffer(buffer!, at: nil, options: AVAudioPlayerNodeBufferOptions.loops, completionHandler: nil)
    }

    @IBAction func stopSound(_ sender: UIButton) {
        audioPlayer.stop()
    }
}

person Simant    schedule 22.04.2018    source источник
comment
Это всегда один и тот же звук? Вы знаете, что вам не нужно перезапускать звук, чтобы изменить его высоту. Также вы можете использовать pitchUnit.rate вместо pitch, что соответствует 1200-м октаве.   -  person Rhythmic Fistman    schedule 23.04.2018
comment
@RhythmicFistman Да, это тот же звук, но если устройство находится в пределах 5 метров от какой-либо точки, оно издает звуковой сигнал, и когда человек приближается к точке, он увеличивает высоту звука или скорость, а когда уходит более чем на 5 метров. звук останавливается. У меня возникла проблема с перезапуском звука, когда устройство возвращается в радиусе 5 метров.   -  person Simant    schedule 23.04.2018


Ответы (1)


Проблема заключается в вашей функции playSound.

// interrupt playing sound if you have to
if audioPlayer.isPlaying {
    audioPlayer.stop()
    audioPlayer.play()
}

Вы пытаетесь воспроизвести плеер, только если он уже играет. так что это не имеет никакого смысла. вы можете удалить эти строки и просто использовать только это.

 audioPlayer.play()
person Satizh J    schedule 18.05.2018