95 lines
3.8 KiB
Swift
95 lines
3.8 KiB
Swift
internal import PFFFTLib
|
|
|
|
public final class FFTDouble: PFFFTProtocol {
|
|
let ptr: OpaquePointer
|
|
let n: Int
|
|
let type: FFTType
|
|
|
|
static let sharedCache = SetupCache<Element>()
|
|
|
|
public static func setup(for n: Int, type: FFTType) throws -> FFTDouble {
|
|
try sharedCache.get(for: n, type: type)
|
|
}
|
|
|
|
public init(n: Int, type: FFTType) throws {
|
|
guard let ptr = pffftd_new_setup(Int32(n), pffft_transform_t(type)) else { throw FFTError.invalidSize }
|
|
self.ptr = ptr
|
|
self.n = n
|
|
self.type = type
|
|
}
|
|
|
|
|
|
func transform(_ input: borrowing Buffer<Element>, _ output: borrowing Buffer<Element>, _ work: borrowing Buffer<Element>?, _ dir: pffft_direction_t) {
|
|
checkFftBufferCounts(n: n, type: type, input: input, output: output, work: work)
|
|
|
|
let workAddress: UnsafeMutablePointer<Element>! = switch work {
|
|
case let .some(b): b.baseAddress
|
|
case .none: nil
|
|
}
|
|
pffftd_transform_ordered(ptr, input.baseAddress, output.baseAddress, workAddress, dir)
|
|
}
|
|
|
|
func transformUnordered(_ input: borrowing Buffer<Double>, _ output: borrowing Buffer<Double>, _ work: borrowing Buffer<Double>?, _ dir: pffft_direction_t) {
|
|
checkFftBufferCounts(n: n, type: type, input: input, output: output, work: work)
|
|
|
|
let workAddress: UnsafeMutablePointer<Double>! = switch work {
|
|
case let .some(b): b.baseAddress
|
|
case .none: nil
|
|
}
|
|
pffftd_transform(ptr, input.baseAddress, output.baseAddress, workAddress, dir)
|
|
}
|
|
|
|
|
|
public func forward(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, work: borrowing Buffer<Double>?) {
|
|
transform(input, output, work, PFFFT_FORWARD)
|
|
}
|
|
|
|
public func inverse(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, work: borrowing Buffer<Double>?) {
|
|
transform(input, output, work, PFFFT_BACKWARD)
|
|
}
|
|
|
|
public func forwardUnordered(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, work: borrowing Buffer<Double>?) {
|
|
transformUnordered(input, output, work, PFFFT_FORWARD)
|
|
}
|
|
|
|
public func inverseUnordered(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, work: borrowing Buffer<Double>?) {
|
|
transformUnordered(input, output, work, PFFFT_BACKWARD)
|
|
}
|
|
|
|
|
|
public func reorderSpectrum(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>) {
|
|
checkFftBufferCounts(n: n, type: type, input: input, output: output, work: nil)
|
|
pffftd_zreorder(ptr, input.baseAddress, output.baseAddress, PFFFT_FORWARD)
|
|
}
|
|
|
|
public func convolveAccumulate(dftA: borrowing Buffer<Double>, dftB: borrowing Buffer<Double>, dftAB: borrowing Buffer<Double>, scaling: Double) {
|
|
checkConvolveBufferCounts(n: n, type: type, a: dftA, b: dftB, ab: dftAB)
|
|
pffftd_zconvolve_accumulate(ptr, dftA.baseAddress, dftB.baseAddress, dftAB.baseAddress, scaling)
|
|
}
|
|
|
|
public func convolve(dftA: borrowing Buffer<Double>, dftB: borrowing Buffer<Double>, dftAB: borrowing Buffer<Double>, scaling: Double) {
|
|
checkConvolveBufferCounts(n: n, type: type, a: dftA, b: dftB, ab: dftAB)
|
|
pffftd_zconvolve_no_accu(ptr, dftA.baseAddress, dftB.baseAddress, dftAB.baseAddress, scaling)
|
|
}
|
|
|
|
public static func minFftSize(for type: FFTType) -> Int {
|
|
Int(pffftd_min_fft_size(pffft_transform_t(type)))
|
|
}
|
|
|
|
public static func isValidSize(_ n: Int, for type: FFTType) -> Bool {
|
|
pffftd_is_valid_size(Int32(n), pffft_transform_t(type)) != 0
|
|
}
|
|
|
|
public static func nearestValidSize(_ n: Int, for type: FFTType, higher: Bool) -> Int {
|
|
Int(pffftd_nearest_transform_size(Int32(n), pffft_transform_t(type), higher ? 1 : 0))
|
|
}
|
|
|
|
deinit {
|
|
pffftd_destroy_setup(ptr)
|
|
}
|
|
}
|
|
|
|
extension Double: FFTElement {
|
|
public typealias FFTImpl = FFTDouble
|
|
}
|