Swift 4: обнаружение самой сильной частоты или наличия частоты в аудиопотоке. - PullRequest
0 голосов
/ 26 ноября 2018

Я пишу приложение, которое должно определить частоту в аудиопотоке.Я прочитал около миллиона статей и у меня проблемы с пересечением финишной черты.У меня есть мои аудиоданные, поступающие мне в этой функции через AVFoundation Framework от Apple.

Я пользуюсь Swift 4.2 и пробовал поиграть с функциями FFT, но в данный момент они мне не по вкусу.

Есть мысли?

// get's the data as a call back for the AVFoundation framework.
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    // prints the whole sample buffer and tells us alot of information about what's inside
    print(sampleBuffer);

    // create a buffer, ready out the data, and use the CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer method to put
    // it into a buffer
    var buffer: CMBlockBuffer? = nil
    var audioBufferList = AudioBufferList(mNumberBuffers: 1,
                                          mBuffers: AudioBuffer(mNumberChannels: 1, mDataByteSize: 0, mData: nil))
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, bufferListSizeNeededOut: nil, bufferListOut: &audioBufferList, bufferListSize: MemoryLayout<AudioBufferList>.size, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: UInt32(kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment), blockBufferOut: &buffer);

    let abl = UnsafeMutableAudioBufferListPointer(&audioBufferList)
    var sum:Int64 = 0
    var count:Int = 0
    var bufs:Int = 0

    var max:Int64 = 0;
    var min:Int64 = 0

    // loop through the samples and check for min's and maxes.
    for buff in abl {
        let samples = UnsafeMutableBufferPointer<Int16>(start: UnsafeMutablePointer(OpaquePointer(buff.mData)),
                                                        count: Int(buff.mDataByteSize)/MemoryLayout<Int16>.size)
        for sample in samples {
            let s = Int64(sample)
            sum = (sum + s*s)
            count += 1

            if(s > max) {
                max = s;
            }

            if(s < min) {
                min = s;
            }

            print(sample)
        }
        bufs += 1
    }

    // debug
    print("min - \(min), max = \(max)");

    // update the interface
    DispatchQueue.main.async {
        self.frequencyDataOutLabel.text = "min - \(min), max = \(max)";
    }

    // stop the capture session
    self.captureSession.stopRunning();
}

1 Ответ

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

После долгих исследований я обнаружил, что ответ заключается в использовании метода БПФ (быстрое преобразование Фурье).Он берет исходные данные из кода iPhone выше и преобразует его в массив значений, представляющих величину каждой частоты в полосах.

Многое здесь относится к открытому коду https://github.com/jscalo/tempi-fft, который создал визуализатор, который собирает данные и отображает их.Оттуда это было вопросом манипулирования им, чтобы удовлетворить потребности.В моем случае я искал частоты выше человеческого слуха (диапазон 20 кГц).Сканируя вторую половину массива в коде tempi-fft, я смог определить, присутствуют ли частоты, которые я искал, достаточно громко.

...