Как реализовать прослушиватель или while (true), чтобы остановить прокрутку графика сигнала после завершения записи в Swift с использованием AudioKit - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть система, которая использует различные классы из AudioKit для записи входного сигнала микрофона и сохранения его в файл, с максимальной продолжительностью 30 с, и одновременно во время записи выходной сигнал отображается на графике сигнала с использованием EZAudioPlot.

Моя проблема в том, что я использую кнопку записи в стиле Snapchat, которая начинает запись / черчение при событии касания и прекращает запись / черчение при событии касания (внутри и снаружи) - это означает, что когда пользователь продолжает удерживатьЕсли кнопка записи длиннее максимальной длительности (как это иногда бывает), форма сигнала на выходе микрофона продолжает отображаться, несмотря на завершение записи.Я спрашиваю, есть ли способ в Swift / AudioKit постоянно «слушать», чтобы рекордер прекратил запись, сродни чему-то вроде

while true
{
    if recorder.isRecording() == false
    {
        plot.pause()
    }
}  

после нажатия кнопки, но до ее отпускания?Если бы был какой-то способ прослушивать бесконечно, чтобы рекордер закончил запись между нажатой кнопкой и отпусканием кнопки, это очень легко решило бы мою проблему.Существует ли такая функциональность в какой-либо форме в Swift или AudioKit?

Мой код выглядит следующим образом (нерелевантный код опущен):

import UIKit
import AudioKit
import AudioKitUI

// Define maximum recording time in seconds

let maxRecordingTime = 30.0

class ViewController: UIViewController
{
    var microphone : AKMicrophone!
    var mixer : AKMixer!
    var waveformBooster: AKBooster!
    var outputBooster : AKBooster!
    var exportTape : AKAudioFile!
    var recorder : AKNodeRecorder!
    var player : AKClipPlayer!
    var circleView : CircleView!
    var plot : AKNodeOutputPlot!

    @IBOutlet var startRecordingButton: CircularButton!
    @IBOutlet var playRecordingButton: UIButton!
    @IBOutlet var waveformPlot: EZAudioPlot!

    override func viewDidLoad()
    {
        super.viewDidLoad()

        microphone = AKMicrophone()
        mixer = AKMixer(microphone)

        // Initialise booster to set monitoring level to zero - this ensures that
        // microphone output is recorded but not sent to main audio output

        outputBooster = AKBooster(mixer)
        outputBooster.gain = 0

        // Initialise booster to set waveform display gain so that waveform can be set to display
        // only when the app is recording

        waveformBooster = AKBooster(microphone)
        waveformBooster.gain = 0

        AudioKit.output = outputBooster
        try!AudioKit.start()

        // Initialise file to store recorder output and set recorder to route mixer
        // output to file

        exportTape = try! AKAudioFile(name: "ExportTape")
        recorder = try! AKNodeRecorder(node: mixer, file: exportTape)

        recorder.durationToRecord = maxRecordingTime

        plot = AKNodeOutputPlot(waveformBooster, frame: waveformPlot.bounds)
        setupWaveformPlot()
    }

    @IBAction func startRecording(_ sender: UIButton)
    {
        // Delete contents of output file so it can be rewritten

        try! recorder.reset()

        // Perform various tasks related to getting the plot ready
        // to be rewritten to in the event of several recordings being made

        updateWaveformPlot()

        // Start the microphone and

        microphone.start()
        waveformBooster.gain = 1

        animateRecordingButton()

        do
        {
            try recorder?.record()
        } catch
        {
            AKLog("Couldn't record")
        }
    }

    @IBAction func stopRecording(_ sender: UIButton)
    {
        microphone.stop()
        waveformBooster.gain = 0
        recorder.stop()

        plot.pause()
    }

    @IBAction func playRecording(_ sender: UIButton)
    {
        let player = try! AKAudioPlayer(file: exportTape)

        if player.isStarted == false
        {
            AudioKit.output = player
            player.play()
        }
    }

    func setupWaveformPlot()
    {
        plot.plotType = .rolling
        plot.clipsToBounds = true
        plot.shouldFill = true
        plot.shouldMirror = true
        plot.color = UIColor.white
        plot.backgroundColor = UIColor.black

        // Set the gain of the plot to control range of values displayed on the waveform plot

        plot.gain = 25
        waveformPlot.addSubview(plot)
    }

    func updateWaveformPlot()
    {
        plot.clear()
        plot.resume()

        // Set rolling history length to correct value for 30s
        // such that waveform fills whole plot with no scrolling

        plot.setRollingHistoryLength(Int32(Float(1284)))
    }
}

1 Ответ

0 голосов
/ 11 декабря 2018

В итоге я реализовал поведение, за которым следовал, с помощью таймера, что-то вроде:

var recordingTimer = Timer!
let maxRecordingTime = 30.0    

if recordingTimer == nil
                {
                    recordingTimer = Timer.scheduledTimer(withTimeInterval: maxRecordingTime, repeats: false)
                    {
                        timer in
                        self.plot.pause()
                    }
...