Разложение Байтового буфера данных для Uint32 - PullRequest
0 голосов
/ 18 октября 2018

Я записываю аудио с помощью AVCaptureSession.В моей функции обратного вызова для обработки захваченных данных я поместил поток в структуру данных (байтовый буфер).Кажется, что Data - это UInt8 (имеет смысл для байтового буфера), но я считаю, что данные потока - это UInt32.

Я не уверен, что из следующего я должен делать, но я не могу получить какой-либоиз них на работу.Должен ли я:

  1. преобразовать данные в UInt32 вместо UInt8?
  2. При чтении из данных взять 4 байта для создания UInt32?
  3. Изменить сеанс захватав UInt8?
  4. Отказаться от структуры данных и создать свою собственную?

Моя функция обратного вызова:

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    var audioBufferList = AudioBufferList()
    var data = Data()
    var blockBuffer: CMBlockBuffer?

    // Put the sample buffer in to a list of audio buffers (audioBufferList)
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, bufferListSizeNeededOut: nil, bufferListOut: &audioBufferList, bufferListSize: MemoryLayout<AudioBufferList>.size, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: 0, blockBufferOut: &blockBuffer)
    // Extract the BufferList in to an array of buffers
    let buffers = UnsafeBufferPointer<AudioBuffer>(start: &audioBufferList.mBuffers, count: Int(audioBufferList.mNumberBuffers))
    // for each buffer, extract the frame.  There should only be one buffer as we are recording in mono!
    for audioBuffer in buffers {
        assert(audioBuffer.mNumberChannels == 1)        // it should always be 1 for mono channel
        let frame = audioBuffer.mData?.assumingMemoryBound(to: UInt8.self)
        data.append(frame!, count: Int(audioBuffer.mDataByteSize) / 8)
    }

    // limit how much of the sample we pass through.
    viewDelegate?.gotSoundData(data.prefix(MAX_POINTS))
}

Все функции gotSoundData переходят из представления вколичество подпредставлений для обработки

func addSamples(samples: Data) {
    //if (isHidden) { return }

    samples.forEach { sample in
        [...process each byte...]
    }
}

Я вижу, что Data.append имеет определение:

mutating func append(_ bytes: UnsafePointer<UInt8>, count: Int)

1 Ответ

0 голосов
/ 20 октября 2018

Меггар помог мне сконцентрироваться на варианте 4 - используя мою собственную структуру [Int16].Если кого-то интересует вариант 1, просмотрите эту ссылку, которую я нашел позже, которая расширяет Данные для большего количества типов данных: тип номера Swift туда и обратно в Данные / 1002 *

функция обратного вызова:

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    var audioBufferList = AudioBufferList()
    var blockBuffer: CMBlockBuffer?

    // Put the sample buffer in to a list of audio buffers (audioBufferList)
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, bufferListSizeNeededOut: nil, bufferListOut: &audioBufferList, bufferListSize: MemoryLayout<AudioBufferList>.size, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: 0, blockBufferOut: &blockBuffer)
    // Extract the BufferList in to an array of buffers
    let audioBuffers = UnsafeBufferPointer<AudioBuffer>(start: &audioBufferList.mBuffers, count: Int(audioBufferList.mNumberBuffers))
    // For each buffer, extract the samples
    for audioBuffer in audioBuffers {
        let samplesCount = Int(audioBuffer.mDataByteSize) / MemoryLayout<Int16>.size
        let samplesPointer = audioBufferList.mBuffers.mData!.bindMemory(to: Int16.self, capacity: samplesCount)
        let samples = UnsafeMutableBufferPointer<Int16>(start: samplesPointer, count: samplesCount)
        //convert to a "safe" array for ease of use in delegate.
        var samplesArray:[Int16] = []
        for sample in samples {
            samplesArray.append(sample)
        }
        viewDelegate?.gotSample(samplesArray)
    }        
}

и функция потребления остается практически неизменной:

func addSamples(samples: [Int16]) {
    samples.forEach { sample in
        [...process each Int16...]
    }
}
...