move pffft
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,5 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/.build
|
/.build
|
||||||
/Packages
|
|
||||||
xcuserdata/
|
xcuserdata/
|
||||||
DerivedData/
|
DerivedData/
|
||||||
.swiftpm/configuration/registries.json
|
.swiftpm/configuration/registries.json
|
||||||
|
|||||||
@@ -9,35 +9,22 @@ let package = Package(
|
|||||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||||
.library(
|
.library(
|
||||||
name: "EcgSynKit",
|
name: "EcgSynKit",
|
||||||
targets: ["EcgSynKit"]),
|
targets: ["EcgSynKit"]
|
||||||
|
),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(url: "https://github.com/apple/swift-algorithms", from: "1.2.0"),
|
.package(url: "https://github.com/apple/swift-algorithms", from: "1.2.0"),
|
||||||
// .package(url: "https://github.com/AudioKit/KissFFT.git", from: "1.0.0")
|
.package(path: "./Packages/KissFFT/"),
|
||||||
.package(path: "./Packages/KissFFT/")
|
.package(path: "./Packages/PFFFT/"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
|
||||||
// Targets can depend on other targets in this package and products from dependencies.
|
|
||||||
.target(
|
.target(
|
||||||
name: "PFFFT",
|
name: "EcgSynKit",
|
||||||
publicHeadersPath: "include",
|
dependencies: [
|
||||||
cSettings: [
|
.product(name: "PFFFT", package: "PFFFT"),
|
||||||
.define("PFFFT_SCALVEC_ENABLED", to: "1"),
|
.product(name: "Algorithms", package: "swift-algorithms"),
|
||||||
.define("_USE_MATH_DEFINES"),
|
|
||||||
.define("NDEBUG"),
|
|
||||||
.unsafeFlags(["-O3", "-std=c99"]),
|
|
||||||
.unsafeFlags(["-mavx"], .when(platforms: [.linux, .macOS])),
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.target(
|
|
||||||
name: "EcgSynKit",
|
|
||||||
dependencies: [
|
|
||||||
.target(name: "PFFFT"),
|
|
||||||
.product(name: "Algorithms", package: "swift-algorithms"),
|
|
||||||
.product(name: "KissFFT", package: "kissfft")
|
|
||||||
]
|
|
||||||
),
|
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "EcgSynKitTests",
|
name: "EcgSynKitTests",
|
||||||
dependencies: ["EcgSynKit"]
|
dependencies: ["EcgSynKit"]
|
||||||
|
|||||||
8
Packages/PFFFT/.gitignore
vendored
Normal file
8
Packages/PFFFT/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.DS_Store
|
||||||
|
/.build
|
||||||
|
/Packages
|
||||||
|
xcuserdata/
|
||||||
|
DerivedData/
|
||||||
|
.swiftpm/configuration/registries.json
|
||||||
|
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||||
|
.netrc
|
||||||
35
Packages/PFFFT/Package.swift
Normal file
35
Packages/PFFFT/Package.swift
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// swift-tools-version: 6.0
|
||||||
|
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||||
|
|
||||||
|
import PackageDescription
|
||||||
|
|
||||||
|
let package = Package(
|
||||||
|
name: "PFFFT",
|
||||||
|
products: [
|
||||||
|
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||||
|
.library(
|
||||||
|
name: "PFFFT",
|
||||||
|
targets: ["PFFFT", "PFFFTLib"]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
.target(
|
||||||
|
name: "PFFFTLib",
|
||||||
|
publicHeadersPath: "include",
|
||||||
|
cSettings: [
|
||||||
|
.define("PFFFT_SCALVEC_ENABLED", to: "1"),
|
||||||
|
.define("_USE_MATH_DEFINES"),
|
||||||
|
.define("NDEBUG"),
|
||||||
|
.unsafeFlags(["-O3", "-std=c99"]),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
.target(
|
||||||
|
name: "PFFFT",
|
||||||
|
dependencies: ["PFFFTLib"]
|
||||||
|
),
|
||||||
|
.testTarget(
|
||||||
|
name: "PFFFTTests",
|
||||||
|
dependencies: ["PFFFTLib"]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
29
Packages/PFFFT/Sources/PFFFT/Buffer.swift
Normal file
29
Packages/PFFFT/Sources/PFFFT/Buffer.swift
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
let bufferAlignment = 32
|
||||||
|
|
||||||
|
@frozen
|
||||||
|
public struct Buffer<Element>: ~Copyable {
|
||||||
|
let buffer: UnsafeMutableBufferPointer<Element>
|
||||||
|
|
||||||
|
init(unsafeUninitializedCapacity: Int) {
|
||||||
|
buffer = UnsafeMutableRawBufferPointer.allocate(
|
||||||
|
byteCount: MemoryLayout<Element>.stride * unsafeUninitializedCapacity,
|
||||||
|
alignment: bufferAlignment
|
||||||
|
).bindMemory(to: Element.self)
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
buffer.deallocate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func withUnsafeMutableBufferPointer<R>(_ body: (UnsafeMutableBufferPointer<Element>) throws -> R) rethrows -> R {
|
||||||
|
try body(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Element>) throws -> R) rethrows -> R {
|
||||||
|
try body(UnsafeBufferPointer(buffer))
|
||||||
|
}
|
||||||
|
|
||||||
|
func withUnsafeMutableBytes<R>(_ body: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R {
|
||||||
|
try body(UnsafeMutableRawBufferPointer(buffer))
|
||||||
|
}
|
||||||
|
}
|
||||||
57
Packages/PFFFT/Sources/PFFFT/FFTDoubleImpl.swift
Normal file
57
Packages/PFFFT/Sources/PFFFT/FFTDoubleImpl.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
internal import PFFFTLib
|
||||||
|
|
||||||
|
struct FFTDoubleImpl: FFTImplProtocol {
|
||||||
|
let ptr: OpaquePointer
|
||||||
|
|
||||||
|
init?(n: Int, type: FFTType) {
|
||||||
|
guard let ptr = pffftd_new_setup(Int32(n), pffft_transform_t(type)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
self.ptr = ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func fft(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, work: borrowing Buffer<Double>?, sign: FFTSign) {
|
||||||
|
let work: UnsafeMutablePointer<Double>! = switch work {
|
||||||
|
case let .some(b): b.buffer.baseAddress
|
||||||
|
case .none: nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pffftd_transform_ordered(ptr, input.buffer.baseAddress, output.buffer.baseAddress, work, pffft_direction_t(sign))
|
||||||
|
}
|
||||||
|
|
||||||
|
func fftUnordered(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, work: borrowing Buffer<Double>?, sign: FFTSign) {
|
||||||
|
let work: UnsafeMutablePointer<Double>! = switch work {
|
||||||
|
case let .some(b): b.buffer.baseAddress
|
||||||
|
case .none: nil
|
||||||
|
}
|
||||||
|
pffftd_transform(ptr, input.buffer.baseAddress, output.buffer.baseAddress, work, pffft_direction_t(sign))
|
||||||
|
}
|
||||||
|
|
||||||
|
func zReorder(input: borrowing Buffer<Double>, output: borrowing Buffer<Double>, sign: FFTSign) {
|
||||||
|
pffftd_zreorder(ptr, input.buffer.baseAddress, output.buffer.baseAddress, pffft_direction_t(sign))
|
||||||
|
}
|
||||||
|
|
||||||
|
func zConvolveAccumulate(dftA: borrowing Buffer<Double>, dftB: borrowing Buffer<Double>, dftAB: borrowing Buffer<Double>, scaling: Double) {
|
||||||
|
pffftd_zconvolve_accumulate(ptr, dftA.buffer.baseAddress, dftB.buffer.baseAddress, dftAB.buffer.baseAddress, scaling)
|
||||||
|
}
|
||||||
|
|
||||||
|
func zConvolve(dftA: borrowing Buffer<Double>, dftB: borrowing Buffer<Double>, dftAB: borrowing Buffer<Double>, scaling: Double) {
|
||||||
|
pffftd_zconvolve_no_accu(ptr, dftA.buffer.baseAddress, dftB.buffer.baseAddress, dftAB.buffer.baseAddress, scaling)
|
||||||
|
}
|
||||||
|
|
||||||
|
func minFftSize(for type: FFTType) -> Int {
|
||||||
|
Int(pffftd_min_fft_size(pffft_transform_t(type)))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func isValidSize(_ n: Int, for type: FFTType) -> Bool {
|
||||||
|
pffftd_is_valid_size(Int32(n), pffft_transform_t(type)) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func simdArch() -> String {
|
||||||
|
String(cString: pffftd_simd_arch())
|
||||||
|
}
|
||||||
|
}
|
||||||
57
Packages/PFFFT/Sources/PFFFT/FFTFloatImpl.swift
Normal file
57
Packages/PFFFT/Sources/PFFFT/FFTFloatImpl.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
internal import PFFFTLib
|
||||||
|
|
||||||
|
struct FFTFloatImpl: FFTImplProtocol {
|
||||||
|
let ptr: OpaquePointer
|
||||||
|
|
||||||
|
init?(n: Int, type: FFTType) {
|
||||||
|
guard let ptr = pffft_new_setup(Int32(n), pffft_transform_t(type)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
self.ptr = ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func fft(input: borrowing Buffer<Float>, output: borrowing Buffer<Float>, work: borrowing Buffer<Float>?, sign: FFTSign) {
|
||||||
|
let work: UnsafeMutablePointer<Float>! = switch work {
|
||||||
|
case let .some(b): b.buffer.baseAddress
|
||||||
|
case .none: nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pffft_transform_ordered(ptr, input.buffer.baseAddress, output.buffer.baseAddress, work, pffft_direction_t(sign))
|
||||||
|
}
|
||||||
|
|
||||||
|
func fftUnordered(input: borrowing Buffer<Float>, output: borrowing Buffer<Float>, work: borrowing Buffer<Float>?, sign: FFTSign) {
|
||||||
|
let work: UnsafeMutablePointer<Float>! = switch work {
|
||||||
|
case let .some(b): b.buffer.baseAddress
|
||||||
|
case .none: nil
|
||||||
|
}
|
||||||
|
pffft_transform(ptr, input.buffer.baseAddress, output.buffer.baseAddress, work, pffft_direction_t(sign))
|
||||||
|
}
|
||||||
|
|
||||||
|
func zReorder(input: borrowing Buffer<Float>, output: borrowing Buffer<Float>, sign: FFTSign) {
|
||||||
|
pffft_zreorder(ptr, input.buffer.baseAddress, output.buffer.baseAddress, pffft_direction_t(sign))
|
||||||
|
}
|
||||||
|
|
||||||
|
func zConvolveAccumulate(dftA: borrowing Buffer<Float>, dftB: borrowing Buffer<Float>, dftAB: borrowing Buffer<Float>, scaling: Float) {
|
||||||
|
pffft_zconvolve_accumulate(ptr, dftA.buffer.baseAddress, dftB.buffer.baseAddress, dftAB.buffer.baseAddress, scaling)
|
||||||
|
}
|
||||||
|
|
||||||
|
func zConvolve(dftA: borrowing Buffer<Float>, dftB: borrowing Buffer<Float>, dftAB: borrowing Buffer<Float>, scaling: Float) {
|
||||||
|
pffft_zconvolve_no_accu(ptr, dftA.buffer.baseAddress, dftB.buffer.baseAddress, dftAB.buffer.baseAddress, scaling)
|
||||||
|
}
|
||||||
|
|
||||||
|
func minFftSize(for type: FFTType) -> Int {
|
||||||
|
Int(pffft_min_fft_size(pffft_transform_t(type)))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func isValidSize(_ n: Int, for type: FFTType) -> Bool {
|
||||||
|
pffft_is_valid_size(Int32(n), pffft_transform_t(type)) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
static func nearestValidSize(_ n: Int, for type: FFTType, higher: Bool) -> Int {
|
||||||
|
Int(pffft_nearest_transform_size(Int32(n), pffft_transform_t(type), higher ? 1 : 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func simdArch() -> String {
|
||||||
|
String(cString: pffft_simd_arch())
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Packages/PFFFT/Sources/PFFFT/PFFFT.swift
Normal file
47
Packages/PFFFT/Sources/PFFFT/PFFFT.swift
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
internal import PFFFTLib
|
||||||
|
|
||||||
|
enum FFTType {
|
||||||
|
case real
|
||||||
|
case complex
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FFTSign: Int {
|
||||||
|
case forward = -1
|
||||||
|
case backward = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol FFTImplProtocol {
|
||||||
|
associatedtype Element
|
||||||
|
|
||||||
|
init?(n: Int, type: FFTType)
|
||||||
|
|
||||||
|
func fft(input: borrowing Buffer<Element>, output: borrowing Buffer<Element>, work: borrowing Buffer<Element>?, sign: FFTSign)
|
||||||
|
func fftUnordered(input: borrowing Buffer<Element>, output: borrowing Buffer<Element>, work: borrowing Buffer<Element>?, sign: FFTSign)
|
||||||
|
func zReorder(input: borrowing Buffer<Element>, output: borrowing Buffer<Element>, sign: FFTSign)
|
||||||
|
func zConvolveAccumulate(dftA: borrowing Buffer<Element>, dftB: borrowing Buffer<Element>, dftAB: borrowing Buffer<Element>, scaling: Element)
|
||||||
|
func zConvolve(dftA: borrowing Buffer<Element>, dftB: borrowing Buffer<Element>, dftAB: borrowing Buffer<Element>, scaling: Element)
|
||||||
|
func minFftSize(for type: FFTType) -> Int
|
||||||
|
static func isValidSize(_ n: Int, for type: FFTType) -> Bool
|
||||||
|
static func nearestValidSize(_ n: Int, for type: FFTType, higher: Bool) -> Int
|
||||||
|
static func simdArch() -> String
|
||||||
|
}
|
||||||
|
|
||||||
|
extension pffft_transform_t {
|
||||||
|
@inline(__always)
|
||||||
|
init(_ type: FFTType) {
|
||||||
|
switch type {
|
||||||
|
case .real: self = PFFFT_REAL
|
||||||
|
case .complex: self = PFFFT_COMPLEX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension pffft_direction_t {
|
||||||
|
@inline(__always)
|
||||||
|
init(_ sign: FFTSign) {
|
||||||
|
switch sign {
|
||||||
|
case .forward: self = PFFFT_FORWARD
|
||||||
|
case .backward: self = PFFFT_BACKWARD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
Packages/PFFFT/Sources/PFFFT/SetupCache.swift
Normal file
30
Packages/PFFFT/Sources/PFFFT/SetupCache.swift
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct CacheKey : Hashable {
|
||||||
|
let n: Int
|
||||||
|
let type: FFTType
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetupCache<Impl: FFTImplProtocol> : @unchecked Sendable {
|
||||||
|
private var cache: [CacheKey: Impl?] = [:]
|
||||||
|
|
||||||
|
private let queue = DispatchQueue(label: String(describing: SetupCache.self), attributes: .concurrent)
|
||||||
|
|
||||||
|
func get(for n: Int, type: FFTType) -> Impl? {
|
||||||
|
var setup: Impl??
|
||||||
|
queue.sync {
|
||||||
|
setup = cache[CacheKey(n: n, type: type)]
|
||||||
|
}
|
||||||
|
if setup == nil {
|
||||||
|
queue.sync(flags: .barrier) {
|
||||||
|
setup = cache[CacheKey(n: n, type: type)]
|
||||||
|
if setup == nil {
|
||||||
|
setup = Impl(n: n, type: type)
|
||||||
|
cache[CacheKey(n: n, type: type)] = setup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return setup!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
134
Packages/PFFFT/Sources/PFFFTLib/pffft.c
Normal file
134
Packages/PFFFT/Sources/PFFFTLib/pffft.c
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/* Copyright (c) 2013 Julien Pommier ( pommier@modartt.com )
|
||||||
|
Copyright (c) 2020 Hayati Ayguen ( h_ayguen@web.de )
|
||||||
|
|
||||||
|
Based on original fortran 77 code from FFTPACKv4 from NETLIB
|
||||||
|
(http://www.netlib.org/fftpack), authored by Dr Paul Swarztrauber
|
||||||
|
of NCAR, in 1985.
|
||||||
|
|
||||||
|
As confirmed by the NCAR fftpack software curators, the following
|
||||||
|
FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
|
||||||
|
released under the same terms.
|
||||||
|
|
||||||
|
FFTPACK license:
|
||||||
|
|
||||||
|
http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
|
||||||
|
|
||||||
|
Copyright (c) 2004 the University Corporation for Atmospheric
|
||||||
|
Research ("UCAR"). All rights reserved. Developed by NCAR's
|
||||||
|
Computational and Information Systems Laboratory, UCAR,
|
||||||
|
www.cisl.ucar.edu.
|
||||||
|
|
||||||
|
Redistribution and use of the Software in source and binary forms,
|
||||||
|
with or without modification, is permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
- Neither the names of NCAR's Computational and Information Systems
|
||||||
|
Laboratory, the University Corporation for Atmospheric Research,
|
||||||
|
nor the names of its sponsors or contributors may be used to
|
||||||
|
endorse or promote products derived from this Software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notices, this list of conditions, and the disclaimer below.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions, and the disclaimer below in the
|
||||||
|
documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
PFFFT : a Pretty Fast FFT.
|
||||||
|
|
||||||
|
This file is largerly based on the original FFTPACK implementation, modified in
|
||||||
|
order to take advantage of SIMD instructions of modern CPUs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
ChangeLog:
|
||||||
|
- 2011/10/02, version 1: This is the very first release of this file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pffft.h"
|
||||||
|
|
||||||
|
/* detect compiler flavour */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define COMPILER_MSVC
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define COMPILER_GCC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if defined(COMPILER_GCC)
|
||||||
|
# define ALWAYS_INLINE(return_type) inline return_type __attribute__ ((always_inline))
|
||||||
|
# define NEVER_INLINE(return_type) return_type __attribute__ ((noinline))
|
||||||
|
# define RESTRICT __restrict
|
||||||
|
# define VLA_ARRAY_ON_STACK(type__, varname__, size__) type__ varname__[size__];
|
||||||
|
#elif defined(COMPILER_MSVC)
|
||||||
|
# define ALWAYS_INLINE(return_type) __forceinline return_type
|
||||||
|
# define NEVER_INLINE(return_type) __declspec(noinline) return_type
|
||||||
|
# define RESTRICT __restrict
|
||||||
|
# define VLA_ARRAY_ON_STACK(type__, varname__, size__) type__ *varname__ = (type__*)_alloca(size__ * sizeof(type__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COMPILER_MSVC
|
||||||
|
#pragma warning( disable : 4244 4305 4204 4456 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
vector support macros: the rest of the code is independant of
|
||||||
|
SSE/Altivec/NEON -- adding support for other platforms with 4-element
|
||||||
|
vectors should be limited to these macros
|
||||||
|
*/
|
||||||
|
#include "simd/pf_float.h"
|
||||||
|
|
||||||
|
/* have code comparable with this definition */
|
||||||
|
#define SETUP_STRUCT PFFFT_Setup
|
||||||
|
#define FUNC_NEW_SETUP pffft_new_setup
|
||||||
|
#define FUNC_DESTROY pffft_destroy_setup
|
||||||
|
#define FUNC_TRANSFORM_UNORDRD pffft_transform
|
||||||
|
#define FUNC_TRANSFORM_ORDERED pffft_transform_ordered
|
||||||
|
#define FUNC_ZREORDER pffft_zreorder
|
||||||
|
#define FUNC_ZCONVOLVE_ACCUMULATE pffft_zconvolve_accumulate
|
||||||
|
#define FUNC_ZCONVOLVE_NO_ACCU pffft_zconvolve_no_accu
|
||||||
|
|
||||||
|
#define FUNC_ALIGNED_MALLOC pffft_aligned_malloc
|
||||||
|
#define FUNC_ALIGNED_FREE pffft_aligned_free
|
||||||
|
#define FUNC_SIMD_SIZE pffft_simd_size
|
||||||
|
#define FUNC_MIN_FFT_SIZE pffft_min_fft_size
|
||||||
|
#define FUNC_IS_VALID_SIZE pffft_is_valid_size
|
||||||
|
#define FUNC_NEAREST_SIZE pffft_nearest_transform_size
|
||||||
|
#define FUNC_SIMD_ARCH pffft_simd_arch
|
||||||
|
#define FUNC_VALIDATE_SIMD_A validate_pffft_simd
|
||||||
|
#define FUNC_VALIDATE_SIMD_EX validate_pffft_simd_ex
|
||||||
|
|
||||||
|
#define FUNC_CPLX_FINALIZE pffft_cplx_finalize
|
||||||
|
#define FUNC_CPLX_PREPROCESS pffft_cplx_preprocess
|
||||||
|
#define FUNC_REAL_PREPROCESS_4X4 pffft_real_preprocess_4x4
|
||||||
|
#define FUNC_REAL_PREPROCESS pffft_real_preprocess
|
||||||
|
#define FUNC_REAL_FINALIZE_4X4 pffft_real_finalize_4x4
|
||||||
|
#define FUNC_REAL_FINALIZE pffft_real_finalize
|
||||||
|
#define FUNC_TRANSFORM_INTERNAL pffft_transform_internal
|
||||||
|
|
||||||
|
#define FUNC_COS cosf
|
||||||
|
#define FUNC_SIN sinf
|
||||||
|
|
||||||
|
|
||||||
|
#include "pffft_priv_impl.h"
|
||||||
|
|
||||||
|
|
||||||
6
Packages/PFFFT/Tests/PFFFTTests/PFFFTTests.swift
Normal file
6
Packages/PFFFT/Tests/PFFFTTests/PFFFTTests.swift
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import Testing
|
||||||
|
@testable import PFFFT
|
||||||
|
|
||||||
|
@Test func example() async throws {
|
||||||
|
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import Algorithms
|
import Algorithms
|
||||||
import Foundation
|
import Foundation
|
||||||
import PFFFT
|
import PFFFTLib
|
||||||
|
|
||||||
struct Parameters {
|
struct Parameters {
|
||||||
/// The number of beats to simulate.
|
/// The number of beats to simulate.
|
||||||
@@ -85,6 +85,10 @@ class PfftSetupCache: @unchecked Sendable {
|
|||||||
static let shared = PfftSetupCache()
|
static let shared = PfftSetupCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EcgDerive {
|
||||||
|
let rrpc: [Double]
|
||||||
|
}
|
||||||
|
|
||||||
func stdev(_ data: [Double]) -> Double {
|
func stdev(_ data: [Double]) -> Double {
|
||||||
let n = Double(data.count)
|
let n = Double(data.count)
|
||||||
let mean = data.reduce(0.0, +) / n
|
let mean = data.reduce(0.0, +) / n
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import Testing
|
import Testing
|
||||||
@testable import EcgSynKit
|
@testable import EcgSynKit
|
||||||
@testable import KissFFT
|
|
||||||
|
|
||||||
@Test func fftTest () {
|
@Test func fftTest () {
|
||||||
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||||
|
|||||||
Reference in New Issue
Block a user