0001 http://mattt.me)
0023 import Accelerate
0024
0025
0027 public func fft(input: [Float]) -> [Float] {
0028 var real = [Float](input)
0029 var imaginary = [Float](count: input.count, repeatedValue: 0.0)
0030 var splitComplex = DSPSplitComplex(realp: &real, imagp: &imaginary)
0031
0032 let length = vDSP_Length(floor(log2(Float(input.count))))
0033 let radix = FFTRadix(kFFTRadix2)
0034 let weights = vDSP_create_fftsetup(length, radix)
0035 vDSP_fft_zip(weights, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))
0036
0037 var magnitudes = [Float](count: input.count, repeatedValue: 0.0)
0038 vDSP_zvmags(&splitComplex, 1, &magnitudes, 1, vDSP_Length(input.count))
0039
0040 var normalizedMagnitudes = [Float](count: input.count, repeatedValue: 0.0)
0041 vDSP_vsmul(sqrt(magnitudes), 1, [2.0 / Float(input.count)], &normalizedMagnitudes, 1, vDSP_Length(input.count))
0042
0043 vDSP_destroy_fftsetup(weights)
0044
0045 return normalizedMagnitudes
0046 }
0047
0048 public func fft(input: [Double]) -> [Double] {
0049 var real = [Double](input)
0050 var imaginary = [Double](count: input.count, repeatedValue: 0.0)
0051 var splitComplex = DSPDoubleSplitComplex(realp: &real, imagp: &imaginary)
0052
0053 let length = vDSP_Length(floor(log2(Float(input.count))))
0054 let radix = FFTRadix(kFFTRadix2)
0055 let weights = vDSP_create_fftsetupD(length, radix)
0056 vDSP_fft_zipD(weights, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))
0057
0058 var magnitudes = [Double](count: input.count, repeatedValue: 0.0)
0059 vDSP_zvmagsD(&splitComplex, 1, &magnitudes, 1, vDSP_Length(input.count))
0060
0061 var normalizedMagnitudes = [Double](count: input.count, repeatedValue: 0.0)
0062 vDSP_vsmulD(sqrt(magnitudes), 1, [2.0 / Double(input.count)], &normalizedMagnitudes, 1, vDSP_Length(input.count))
0063
0064 vDSP_destroy_fftsetupD(weights)
0065
0066 return normalizedMagnitudes
0067 }
0068