Доступ к образцам с плавающей запятой AVAudioPCMBuffer для обработки

Я пытаюсь выполнить некоторые вычисления с необработанными образцами PCM mp3-файлов, которые я играю, с графом AVAudioEngine. У меня есть закрытие каждые 44100 выборок, которое обеспечивает AVAudioPCMBuffer. У него есть свойство channelData типа UnsafePointer<UnsafeMutablePointer<Float>>?. Я не работал с указателями в Swift 3, поэтому не понимаю, как получить доступ к этим значениям Float.

У меня есть следующий код, но есть много проблем:

audioPlayerNode.installTap(onBus: 0, 
                           bufferSize: 1024, 
                           format: audioPlayerNode.outputFormat(forBus: 0)) { (pcmBuffer, time) in

let numChans = Int(pcmBuffer.format.channelCount)
let frameLength = pcmBuffer.frameLength
     
if let chans = pcmBuffer.floatChannelData?.pointee {
    for a in 0..<numChans {   
        let samples = chans[a]// samples is type Float.  should be pointer to Floats.
        for b in 0..<flength {
            print("sample: \(b)") // should be samples[b] but that gives error as "samples" is Float
        }
    }
}

Например, как выполнить итерацию по UnsafeMutablePointer<Floats, которые представляют собой N указателей с плавающей запятой, где N — количество каналов в буфере. Я не смог найти обсуждение доступа к образцам буфера в Документах Apple по этому классу.

Я думаю, что основная проблема let samples = chans[a]. Xcode говорит, что chans имеет тип UnsafeMutablePointer<Float>. Но это должно быть ценность NumChannels этих указателей. Вот почему я использую a in 0..<numChans для индексации. Тем не менее, я получаю только Float, когда я это делаю.

РЕДАКТИРОВАТЬ:

хм, кажется, используется chans.advanced(by: a) вместо фиксированных вещей


person Alex Bollbach    schedule 10.03.2017    source источник
comment
Во-первых, проверьте, что если numChans равно 1   -  person dengApro    schedule 07.10.2019


Ответы (1)


Вот что я нашел:

let arraySize = Int(buffer.frameLength)
let samples = Array(UnsafeBufferPointer(start: buffer.floatChannelData![0], count:arraySize))

Это предполагает, что буфер — это имя вашего AVAudioPCMBuffer.

Таким образом, вы можете избежать указателей, что, вероятно, намного проще. Теперь вы можете выполнять поиск по данным с помощью цикла for.

person Logan    schedule 03.05.2017