Как чередовать массивы вещественных и комплексных чисел для использования vDSP_ctoz?

#ios #swift

#iOS #swift

Вопрос:

Синтаксис swift менялся с годами, и этот код, который работал идеально, больше не работает…

 var zerosR = [Float](count: windowSizeOverTwo, repeatedValue: 0.0)
var zerosI = [Float](count: windowSizeOverTwo, repeatedValue: 0.0)
var cplxData = DSPSplitComplex( realp: amp;zerosR, imagp: amp;zerosI )

let xAsComplex = UnsafePointer<DSPComplex>( inputSignal.withUnsafeBufferPointer { $0.baseAddress } )
vDSP_ctoz( xAsComplex, 2, amp;cplxData, 1, vDSP_Length(windowSizeOverTwo) )

vDSP_fft_zrip( setup, amp;cplxData, 1, log2n, FFTDirection(kFFTDirection_Forward) )
  

Каждая строка этого кода показывает ошибку в Swift 4

Я смог преобразовать все, кроме этой строки

 let xAsComplex = UnsafePointer<DSPComplex>( inputSignal.withUnsafeBufferPointer { $0.baseAddress } )
  

это не компилируется с этой ошибкой

Не удается преобразовать значение типа ‘UnsafePointer?’ в ожидаемый тип аргумента ‘UnsafePointer<_>?’

Комментарии:

1. Что такое inputSignal ?

2. inputSignal это массив с плавающими значениями

Ответ №1:

Указатель на хранилище Float элементов в inputSignal массиве должен быть возвращен, чтобы указывать на массив DSPComplex значений:

 let inputSignal: [Float] = ...

inputSignal.withUnsafeBufferPointer {
    floatPtr in
    floatPtr.withMemoryRebound(to: DSPComplex.self) {
        cmplxPtr in
        vDSP_ctoz(cmplxPtr.baseAddress!, 2, amp;cplxData, 1, vDSP_Length(windowSizeOverTwo) )
    }
}
  

Смотрите также Миграцию UnsafeRawPointer для получения дополнительной информации.

Обратите внимание, что эти указатели действительны только во время выполнения замыкания и не должны передаваться извне. Что вы сделали в

 let xAsComplex = UnsafePointer<DSPComplex>( inputSignal.withUnsafeBufferPointer { $0.baseAddress } )
  

на самом деле полагался на неопределенное поведение.