Как реализовать прослушиватель или while(true), чтобы остановить прокрутку графика сигнала после завершения записи в Swift с использованием AudioKit
У меня есть система, которая использует различные классы из 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 ответ
Я закончил тем, что реализовал поведение, которое я преследовал с помощью Таймера, что-то вроде:
var recordingTimer = Timer!
let maxRecordingTime = 30.0
if recordingTimer == nil
{
recordingTimer = Timer.scheduledTimer(withTimeInterval: maxRecordingTime, repeats: false)
{
timer in
self.plot.pause()
}