Как записать звук с AVAudioEngine с позицией поиска, чтобы перезаписать звук? - PullRequest
0 голосов
/ 30 мая 2019

Приложение Apple Memos Recorder может перезаписывать ранее записанный звук. Во время записи вы можете PAUSE вернуться к звуку и записать его снова. Я хочу клонировать эту функцию.

Я создаю AVAudioEngine и устанавливаю TAP на вывод mainMixer и записываю PCMBuffer в файл. Я могу сохранить файл в разных линейных форматах PCM. Проблема в том, что когда я хочу установить AudioFile.framePosition, он вызывает функцию EXTAudioFileSeek(). Эта функция упоминалась в документации Apple: «Поведение этой функции с открытыми для записи файлами не определено». Затем я получаю следующую ошибку:

EXCEPTION (-66568): "seek to frame in audio file"

Это означает, что я не могу использовать эту функцию для поиска позиции в AudioFile, созданной для записи. (Я принимаю это)

Я хочу знать, есть ли у нас еще одна функция в Core Audio, которая помогает мне писать с позиции в AudioFile?

Я следую @ RomanTsopin структуре, и она работает правильно.

var engine = AVAudioEngine()
var file: AVAudioFile?
var player = AVAudioPlayerNode() // if you need play record later

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    file = AVAudioFile(forWriting: URLFor("my_file.caf")!, settings: engine.inputNode.inputFormatForBus(0).settings, error: nil)
    engine.attachNode(player)
    engine.connect(player, to: engine.mainMixerNode, format: engine.mainMixerNode.outputFormatForBus(0)) //configure graph
    engine.startAndReturnError(nil)
}

@IBAction func record(sender: AnyObject) {
    engine.inputNode.installTapOnBus(0, bufferSize: 1024, format: engine.mainMixerNode.outputFormatForBus(0)) { (buffer, time) -> Void in
        self.file?.writeFromBuffer(buffer, error: nil)
        return
    }
}

@IBAction func stop(sender: AnyObject) {
    engine.inputNode.removeTapOnBus(0)
}


func URLFor(filename: String) -> NSURL? {
    if let dirs : [String] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String] {
        let dir = dirs[0] //documents directory
        let path = dir.stringByAppendingPathComponent(filename)
        return NSURL(fileURLWithPath: path)
    }
    return nil
}

После приостановки записи я хочу изменить положение записывающего указателя и записать из этой позиции в файл.

Я собираюсь попробовать AudioFileWritePackets, потому что он получает inStartingPacket (индекс пакета для размещения первого предоставленного пакета.)

Что ты думаешь? Любая идея может помочь, спасибо.

...