From a3f3153c3c0d33daa1f41a05038d44939360971a Mon Sep 17 00:00:00 2001 From: Alejandro Isaza Date: Sun, 1 Apr 2018 12:23:36 -0700 Subject: [PATCH] Add UnsafeMemory abstraction (#77) This simplifies the code dealing with unsafe pointers and allows using existing functions with other collections. Also update the copyright notices. --- LICENSE | 2 +- Package.swift | 2 +- Sources/Surge/Arithmetic.swift | 370 +++++++++--------- Sources/Surge/ArraySliceUnsafeMemory.swift | 43 ++ Sources/Surge/ArrayUnsafeMemory.swift | 43 ++ Sources/Surge/Auxiliary.swift | 226 +++++------ Sources/Surge/ContinuousCollection.swift | 55 --- Sources/Surge/Convolution.swift | 59 ++- Sources/Surge/Exponential.swift | 170 ++++---- Sources/Surge/FFT.swift | 2 +- Sources/Surge/Hyperbolic.swift | 182 +++++---- Sources/Surge/Matrix.swift | 30 +- Sources/Surge/Pointers.swift | 122 +----- Sources/Surge/Power.swift | 34 +- Sources/Surge/Surge.h | 2 +- Sources/Surge/Trigonometric.swift | 266 +++++++------ Sources/Surge/UnsafeMemory.swift | 79 ++++ Sources/Surge/UnsafeMutableMemory.swift | 89 +++++ Surge.playground/Contents.swift | 4 +- Surge.xcodeproj/project.pbxproj | 50 ++- .../xcshareddata/xcschemes/Surge-iOS.xcscheme | 1 + Surge.xcworkspace/contents.xcworkspacedata | 6 +- Tests/SurgeTests/ArithmeticTests.swift | 2 +- Tests/SurgeTests/AuxiliaryTests.swift | 2 +- Tests/SurgeTests/ConvolutionTests.swift | 2 +- Tests/SurgeTests/ExponentialTests.swift | 2 +- Tests/SurgeTests/HyperbolicTests.swift | 2 +- Tests/SurgeTests/MatrixTests.swift | 2 +- Tests/SurgeTests/PowerTests.swift | 3 +- Tests/SurgeTests/TrigonometricTests.swift | 2 +- Tests/SurgeTests/XCTestCase+Surge.swift | 2 +- 31 files changed, 1012 insertions(+), 844 deletions(-) create mode 100644 Sources/Surge/ArraySliceUnsafeMemory.swift create mode 100644 Sources/Surge/ArrayUnsafeMemory.swift delete mode 100644 Sources/Surge/ContinuousCollection.swift create mode 100644 Sources/Surge/UnsafeMemory.swift create mode 100644 Sources/Surge/UnsafeMutableMemory.swift diff --git a/LICENSE b/LICENSE index 38bd42a..3aa05d8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright © 2014 Mattt Thompson (http://mattt.me/) +Copyright © 2014-2018 the Surge contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Package.swift b/Package.swift index c00e420..fbc4fd8 100644 --- a/Package.swift +++ b/Package.swift @@ -1,6 +1,6 @@ // swift-tools-version:4.0 // -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Sources/Surge/Arithmetic.swift b/Sources/Surge/Arithmetic.swift index 973ffd3..e9018b7 100644 --- a/Sources/Surge/Arithmetic.swift +++ b/Sources/Surge/Arithmetic.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,21 +22,21 @@ import Accelerate // MARK: Sum -public func sum(_ x: C) -> Float where C.Iterator.Element == Float { +public func sum(_ x: C) -> Float where C.Element == Float { var result: Float = 0.0 - withUnsafePointersAndCountsTo(x) { x, count -> Void in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_sve(x, 1, pointer, vDSP_Length(count)) + vDSP_sve(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func sum(_ x: C) -> Double where C.Iterator.Element == Double { +public func sum(_ x: C) -> Double where C.Element == Double { var result: Double = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_sveD(x, 1, pointer, vDSP_Length(count)) + vDSP_sveD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -44,41 +44,35 @@ public func sum(_ x: C) -> Double where C.Iterator.Elem // MARK: Sum of Absolute Values -public func asum(_ x: C) -> Float where C.Iterator.Element == Float { - return x.withUnsafeBufferPointer { bufferPointer in - guard let x = bufferPointer.baseAddress else { - return 0 - } - return cblas_sasum(Int32(bufferPointer.count), x, 1) +public func asum(_ x: C) -> Float where C.Element == Float { + return x.withUnsafeMemory { xm in + cblas_sasum(numericCast(xm.count), xm.pointer, numericCast(xm.stride)) } } -public func asum(_ x: C) -> Double where C.Iterator.Element == Double { - return x.withUnsafeBufferPointer { bufferPointer in - guard let x = bufferPointer.baseAddress else { - return 0 - } - return cblas_dasum(Int32(bufferPointer.count), x, 1) +public func asum(_ x: C) -> Double where C.Element == Double { + return x.withUnsafeMemory { xm in + cblas_dasum(numericCast(xm.count), xm.pointer, numericCast(xm.stride)) } } // MARK: Sum of Square Values -public func sumsq(_ x: C) -> Float where C.Iterator.Element == Float { +public func sumsq(_ x: C) -> Float where C.Element == Float { var result: Float = 0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_svesq(x, 1, pointer, vDSP_Length(count)) + vDSP_svesq(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func sumsq(_ x: C) -> Double where C.Iterator.Element == Double { +public func sumsq(_ x: C) -> Double where C.Element == Double { var result: Double = 0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_svesqD(x, 1, pointer, vDSP_Length(count)) + vDSP_svesqD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -86,21 +80,21 @@ public func sumsq(_ x: C) -> Double where C.Iterator.El // MARK: Maximum -public func max(_ x: C) -> Float where C.Iterator.Element == Float { +public func max(_ x: C) -> Float where C.Element == Float { var result: Float = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_maxv(x, 1, pointer, vDSP_Length(count)) + vDSP_maxv(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func max(_ x: C) -> Double where C.Iterator.Element == Double { +public func max(_ x: C) -> Double where C.Element == Double { var result: Double = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_maxvD(x, 1, pointer, vDSP_Length(count)) + vDSP_maxvD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -108,21 +102,21 @@ public func max(_ x: C) -> Double where C.Iterator.Elem // MARK: Minimum -public func min(_ x: C) -> Float where C.Iterator.Element == Float { +public func min(_ x: C) -> Float where C.Element == Float { var result: Float = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_minv(x, 1, pointer, vDSP_Length(count)) + vDSP_minv(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func min(_ x: C) -> Double where C.Iterator.Element == Double { +public func min(_ x: C) -> Double where C.Element == Double { var result: Double = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_minvD(x, 1, pointer, vDSP_Length(count)) + vDSP_minvD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -130,21 +124,21 @@ public func min(_ x: C) -> Double where C.Iterator.Elem // MARK: Mean -public func mean(_ x: C) -> Float where C.Iterator.Element == Float { +public func mean(_ x: C) -> Float where C.Element == Float { var result: Float = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_meanv(x, 1, pointer, vDSP_Length(count)) + vDSP_meanv(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func mean(_ x: C) -> Double where C.Iterator.Element == Double { +public func mean(_ x: C) -> Double where C.Element == Double { var result: Double = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_meanvD(x, 1, pointer, vDSP_Length(count)) + vDSP_meanvD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -152,21 +146,21 @@ public func mean(_ x: C) -> Double where C.Iterator.Ele // MARK: Mean Magnitude -public func meamg(_ x: C) -> Float where C.Iterator.Element == Float { +public func meamg(_ x: C) -> Float where C.Element == Float { var result: Float = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_meamgv(x, 1, pointer, vDSP_Length(count)) + vDSP_meamgv(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func meamg(_ x: C) -> Double where C.Iterator.Element == Double { +public func meamg(_ x: C) -> Double where C.Element == Double { var result: Double = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_meamgvD(x, 1, pointer, vDSP_Length(count)) + vDSP_meamgvD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -174,21 +168,21 @@ public func meamg(_ x: C) -> Double where C.Iterator.El // MARK: Mean Square Value -public func measq(_ x: C) -> Float where C.Iterator.Element == Float { +public func measq(_ x: C) -> Float where C.Element == Float { var result: Float = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_measqv(x, 1, pointer, vDSP_Length(count)) + vDSP_measqv(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result } -public func measq(_ x: C) -> Double where C.Iterator.Element == Double { +public func measq(_ x: C) -> Double where C.Element == Double { var result: Double = 0.0 - withUnsafePointersAndCountsTo(x) { x, count in + x.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in - vDSP_measqvD(x, 1, pointer, vDSP_Length(count)) + vDSP_measqvD(xm.pointer, xm.stride, pointer, numericCast(xm.count)) } } return result @@ -196,21 +190,21 @@ public func measq(_ x: C) -> Double where C.Iterator.El // MARK: Add -public func add(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { +public func add(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { var results = [Float](y) - x.withUnsafeBufferPointer { xbp in + x.withUnsafeMemory { xm in results.withUnsafeMutableBufferPointer { rbp in - cblas_saxpy(Int32(xbp.count), 1.0, xbp.baseAddress, 1, rbp.baseAddress, 1) + cblas_saxpy(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), rbp.baseAddress, 1) } } return results } -public func add(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { +public func add(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { var results = [Double](y) - x.withUnsafeBufferPointer { xbp in + x.withUnsafeMemory { xm in results.withUnsafeMutableBufferPointer { rbp in - cblas_daxpy(Int32(xbp.count), 1.0, xbp.baseAddress, 1, rbp.baseAddress, 1) + cblas_daxpy(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), rbp.baseAddress, 1) } } return results @@ -218,21 +212,21 @@ public func add(_ x: X, _ y: Y // MARK: Subtraction -public func sub(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { +public func sub(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { var results = [Float](y) - x.withUnsafeBufferPointer { xbp in + x.withUnsafeMemory { xm in results.withUnsafeMutableBufferPointer { rbp in - catlas_saxpby(Int32(xbp.count), 1.0, xbp.baseAddress, 1, -1, rbp.baseAddress, 1) + catlas_saxpby(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), -1, rbp.baseAddress, 1) } } return results } -public func sub(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { +public func sub(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { var results = [Double](y) - x.withUnsafeBufferPointer { xbp in + x.withUnsafeMemory { xm in results.withUnsafeMutableBufferPointer { rbp in - catlas_daxpby(Int32(xbp.count), 1.0, xbp.baseAddress, 1, -1, rbp.baseAddress, 1) + catlas_daxpby(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), -1, rbp.baseAddress, 1) } } return results @@ -240,281 +234,283 @@ public func sub(_ x: X, _ y: Y // MARK: Multiply -public func mul(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +public func mul(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { + return withUnsafeMemory(x, y) { xm, ym in + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vDSP_vmul(xp, 1, yp, 1, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + vDSP_vmul(xm.pointer, xm.stride, ym.pointer, ym.stride, rbp.baseAddress!, 1, numericCast(xm.count)) } + return results } - return results } -public func mul(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +public func mul(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { + return withUnsafeMemory(x, y) { xm, ym in + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vDSP_vmulD(xp, 1, yp, 1, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + vDSP_vmulD(xm.pointer, xm.stride, ym.pointer, ym.stride, rbp.baseAddress!, 1, numericCast(xm.count)) } + return results } - return results } // MARK: Divide -public func div(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +/// Elemen-wise vector division. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func div(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vvdivf(rbp.baseAddress!, xp, yp, [Int32(xbp.count)]) + vvdivf(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func div(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +/// Elemen-wise vector division. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func div(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vvdiv(rbp.baseAddress!, xp, yp, [Int32(xbp.count)]) + vvdiv(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Modulo -public func mod(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +/// Elemen-wise modulo. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func mod(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vvfmodf(rbp.baseAddress!, xp, yp, [Int32(xbp.count)]) + vvfmodf(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func mod(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +/// Elemen-wise modulo. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func mod(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vvfmod(rbp.baseAddress!, xp, yp, [Int32(xbp.count)]) + vvfmod(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Remainder -public func remainder(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +/// Elemen-wise remainder. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func remainder(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vvremainderf(rbp.baseAddress!, xp, yp, [Int32(xbp.count)]) + vvremainderf(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func remainder(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } +/// Elemen-wise remainder. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func remainder(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { rbp in - vvremainder(rbp.baseAddress!, xp, yp, [Int32(xbp.count)]) + vvremainder(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Square Root -public func sqrt(_ x: C) -> [Float] where C.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - withUnsafePointersAndCountsTo(x) { x, count in +/// Elemen-wise square root. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func sqrt(_ x: C) -> [Float] where C.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { bufferPointer in - vvsqrtf(bufferPointer.baseAddress!, x, [Int32(count)]) + vvsqrtf(bufferPointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func sqrt(_ x: C) -> [Double] where C.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - withUnsafePointersAndCountsTo(x) { x, count in +/// Elemen-wise square root. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func sqrt(_ x: C) -> [Double] where C.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) results.withUnsafeMutableBufferPointer { bufferPointer in - vvsqrt(bufferPointer.baseAddress!, x, [Int32(count)]) + vvsqrt(bufferPointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Dot Product -public func dot(_ x: X, _ y: Y) -> Float where X.Iterator.Element == Float, Y.Iterator.Element == Float { - precondition(x.count == y.count, "Vectors must have equal count") +public func dot(_ x: X, _ y: Y) -> Float where X.Element == Float, Y.Element == Float { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.count == ym.count, "Vectors must have equal count") - var result: Float = 0.0 - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } + var result: Float = 0.0 withUnsafeMutablePointer(to: &result) { pointer in - vDSP_dotpr(xp, 1, yp, 1, pointer, vDSP_Length(xbp.count)) + vDSP_dotpr(xm.pointer, xm.stride, ym.pointer, ym.stride, pointer, numericCast(xm.count)) } - } - return result + return result + } } -public func dot(_ x: X, _ y: Y) -> Double where X.Iterator.Element == Double, Y.Iterator.Element == Double { - precondition(x.count == y.count, "Vectors must have equal count") +public func dot(_ x: X, _ y: Y) -> Double where X.Element == Double, Y.Element == Double { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.count == ym.count, "Vectors must have equal count") - var result: Double = 0.0 - withUnsafeBufferPointersTo(x, y) { xbp, ybp in - guard let xp = xbp.baseAddress, let yp = ybp.baseAddress else { - return - } + var result: Double = 0.0 withUnsafeMutablePointer(to: &result) { pointer in - vDSP_dotprD(xp, 1, yp, 1, pointer, vDSP_Length(xbp.count)) + vDSP_dotprD(xm.pointer, xm.stride, ym.pointer, ym.stride, pointer, numericCast(xm.count)) } - } - return result + return result + } } // MARK: - Distance -public func dist(_ x: X, _ y: Y) -> Float where X.Iterator.Element == Float, Y.Iterator.Element == Float { +public func dist(_ x: X, _ y: Y) -> Float where X.Element == Float, Y.Element == Float { precondition(x.count == y.count, "Vectors must have equal count") let sub = x - y var squared = [Float](repeating: 0.0, count: numericCast(x.count)) squared.withUnsafeMutableBufferPointer { bufferPointer in - vDSP_vsq(sub, 1, bufferPointer.baseAddress!, 1, vDSP_Length(x.count)) + vDSP_vsq(sub, 1, bufferPointer.baseAddress!, 1, numericCast(x.count)) } return sqrt(sum(squared)) } -public func dist(_ x: X, _ y: Y) -> Double where X.Iterator.Element == Double, Y.Iterator.Element == Double { +public func dist(_ x: X, _ y: Y) -> Double where X.Element == Double, Y.Element == Double { precondition(x.count == y.count, "Vectors must have equal count") let sub = x - y var squared = [Double](repeating: 0.0, count: numericCast(x.count)) squared.withUnsafeMutableBufferPointer { bufferPointer in - vDSP_vsqD(sub, 1, bufferPointer.baseAddress!, 1, vDSP_Length(x.count)) + vDSP_vsqD(sub, 1, bufferPointer.baseAddress!, 1, numericCast(x.count)) } return sqrt(sum(squared)) } // MARK: - Operators -public func + (lhs: L, rhs: R) -> [Float] where L.Iterator.Element == Float, R.Iterator.Element == Float { +public func + (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { return add(lhs, rhs) } -public func + (lhs: L, rhs: R) -> [Double] where L.Iterator.Element == Double, R.Iterator.Element == Double { +public func + (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { return add(lhs, rhs) } -public func + (lhs: L, rhs: Float) -> [Float] where L.Iterator.Element == Float { +public func + (lhs: L, rhs: Float) -> [Float] where L.Element == Float { return add(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } -public func + (lhs: L, rhs: Double) -> [Double] where L.Iterator.Element == Double { +public func + (lhs: L, rhs: Double) -> [Double] where L.Element == Double { return add(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -public func - (lhs: L, rhs: R) -> [Float] where L.Iterator.Element == Float, R.Iterator.Element == Float { +public func - (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { return sub(lhs, rhs) } -public func - (lhs: L, rhs: R) -> [Double] where L.Iterator.Element == Double, R.Iterator.Element == Double { +public func - (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { return sub(lhs, rhs) } -public func - (lhs: L, rhs: Float) -> [Float] where L.Iterator.Element == Float { +public func - (lhs: L, rhs: Float) -> [Float] where L.Element == Float { return sub(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } -public func - (lhs: L, rhs: Double) -> [Double] where L.Iterator.Element == Double { +public func - (lhs: L, rhs: Double) -> [Double] where L.Element == Double { return sub(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -public func / (lhs: L, rhs: R) -> [Float] where L.Iterator.Element == Float, R.Iterator.Element == Float { +public func / (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { return div(lhs, rhs) } -public func / (lhs: L, rhs: R) -> [Double] where L.Iterator.Element == Double, R.Iterator.Element == Double { +public func / (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { return div(lhs, rhs) } -public func / (lhs: L, rhs: Float) -> [Float] where L.Iterator.Element == Float { +public func / (lhs: L, rhs: Float) -> [Float] where L.Element == Float { return div(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } -public func / (lhs: L, rhs: Double) -> [Double] where L.Iterator.Element == Double { +public func / (lhs: L, rhs: Double) -> [Double] where L.Element == Double { return div(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -public func * (lhs: L, rhs: R) -> [Float] where L.Iterator.Element == Float, R.Iterator.Element == Float { +public func * (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { return mul(lhs, rhs) } -public func * (lhs: L, rhs: R) -> [Double] where L.Iterator.Element == Double, R.Iterator.Element == Double { +public func * (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { return mul(lhs, rhs) } -public func * (lhs: L, rhs: Float) -> [Float] where L.Iterator.Element == Float { +public func * (lhs: L, rhs: Float) -> [Float] where L.Element == Float { return mul(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } -public func * (lhs: L, rhs: Double) -> [Double] where L.Iterator.Element == Double { +public func * (lhs: L, rhs: Double) -> [Double] where L.Element == Double { return mul(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -public func % (lhs: L, rhs: R) -> [Float] where L.Iterator.Element == Float, R.Iterator.Element == Float { +public func % (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { return mod(lhs, rhs) } -public func % (lhs: L, rhs: R) -> [Double] where L.Iterator.Element == Double, R.Iterator.Element == Double { +public func % (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { return mod(lhs, rhs) } -public func % (lhs: L, rhs: Float) -> [Float] where L.Iterator.Element == Float { +public func % (lhs: L, rhs: Float) -> [Float] where L.Element == Float { return mod(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } -public func % (lhs: L, rhs: Double) -> [Double] where L.Iterator.Element == Double { +public func % (lhs: L, rhs: Double) -> [Double] where L.Element == Double { return mod(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } infix operator • -public func • (lhs: L, rhs: R) -> Double where L.Iterator.Element == Double, R.Iterator.Element == Double { +public func • (lhs: L, rhs: R) -> Double where L.Element == Double, R.Element == Double { return dot(lhs, rhs) } -public func • (lhs: L, rhs: R) -> Float where L.Iterator.Element == Float, R.Iterator.Element == Float { +public func • (lhs: L, rhs: R) -> Float where L.Element == Float, R.Element == Float { return dot(lhs, rhs) } diff --git a/Sources/Surge/ArraySliceUnsafeMemory.swift b/Sources/Surge/ArraySliceUnsafeMemory.swift new file mode 100644 index 0000000..96d099f --- /dev/null +++ b/Sources/Surge/ArraySliceUnsafeMemory.swift @@ -0,0 +1,43 @@ +// Copyright © 2014-2018 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 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 IN +// THE SOFTWARE. + +import Foundation + +extension ArraySlice: UnsafeMemoryAccessible, UnsafeMutableMemoryAccessible { + public func withUnsafeMemory(_ action: (UnsafeMemory) throws -> Result) rethrows -> Result { + return try withUnsafeBufferPointer { ptr in + guard let base = ptr.baseAddress else { + fatalError("ArraySlice is missing its pointer") + } + let memory = UnsafeMemory(pointer: base, stride: 1, count: ptr.count) + return try action(memory) + } + } + + public mutating func withUnsafeMutableMemory(_ action: (UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try withUnsafeMutableBufferPointer { ptr in + guard let base = ptr.baseAddress else { + fatalError("ArraySlice is missing its pointer") + } + let memory = UnsafeMutableMemory(pointer: base, stride: 1, count: ptr.count) + return try action(memory) + } + } +} diff --git a/Sources/Surge/ArrayUnsafeMemory.swift b/Sources/Surge/ArrayUnsafeMemory.swift new file mode 100644 index 0000000..97bf054 --- /dev/null +++ b/Sources/Surge/ArrayUnsafeMemory.swift @@ -0,0 +1,43 @@ +// Copyright © 2014-2018 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 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 IN +// THE SOFTWARE. + +import Foundation + +extension Array: UnsafeMemoryAccessible, UnsafeMutableMemoryAccessible { + public func withUnsafeMemory(_ action: (UnsafeMemory) throws -> Result) rethrows -> Result { + return try withUnsafeBufferPointer { ptr in + guard let base = ptr.baseAddress else { + fatalError("Array is missing its pointer") + } + let memory = UnsafeMemory(pointer: base, stride: 1, count: ptr.count) + return try action(memory) + } + } + + public mutating func withUnsafeMutableMemory(_ action: (UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try withUnsafeMutableBufferPointer { ptr in + guard let base = ptr.baseAddress else { + fatalError("Array is missing its pointer") + } + let memory = UnsafeMutableMemory(pointer: base, stride: 1, count: ptr.count) + return try action(memory) + } + } +} diff --git a/Sources/Surge/Auxiliary.swift b/Sources/Surge/Auxiliary.swift index 83550e3..273c20f 100644 --- a/Sources/Surge/Auxiliary.swift +++ b/Sources/Surge/Auxiliary.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,27 +22,29 @@ import Accelerate // MARK: Absolute Value -public func abs(_ x: C) -> [Double] where C.Iterator.Element == Double { +/// Elemen-wise absolute value. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func abs(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvfabs(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvfabs(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results } -public func abs(_ x: C) -> [Float] where C.Iterator.Element == Float { +/// Elemen-wise absolute value. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func abs(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvfabsf(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvfabsf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results @@ -50,27 +52,29 @@ public func abs(_ x: C) -> [Float] where C.Iterator.Ele // MARK: Ceiling -public func ceil(_ x: C) -> [Float] where C.Iterator.Element == Float { +/// Elemen-wise ceiling. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func ceil(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvceilf(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvceilf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results } -public func ceil(_ x: C) -> [Double] where C.Iterator.Element == Double { +/// Elemen-wise ceiling. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func ceil(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvceil(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvceil(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results @@ -78,34 +82,28 @@ public func ceil(_ x: C) -> [Double] where C.Iterator.E // MARK: Clip -public func clip(_ x: C, low: Float, high: Float) -> [Float] where C.Iterator.Element == Float { +public func clip(_ x: C, low: Float, high: Float) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } + x.withUnsafeMemory { xm in var y = low var z = high - withUnsafePointersTo(&y, &z) { y, z in - vDSP_vclip(xp, 1, y, z, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + withUnsafePointers(&y, &z) { y, z in + vDSP_vclip(xm.pointer, xm.stride, y, z, rbp.baseAddress!, 1, numericCast(xm.count)) } } } return results } -public func clip(_ x: C, low: Double, high: Double) -> [Double] where C.Iterator.Element == Double { +public func clip(_ x: C, low: Double, high: Double) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } + x.withUnsafeMemory { xm in var y = low var z = high - withUnsafePointersTo(&y, &z) { y, z in - vDSP_vclipD(xp, 1, y, z, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + withUnsafePointers(&y, &z) { y, z in + vDSP_vclipD(xm.pointer, xm.stride, y, z, rbp.baseAddress!, 1, numericCast(xm.count)) } } } @@ -114,27 +112,25 @@ public func clip(_ x: C, low: Double, high: Double) -> // MARK: Copy Sign -public func copysign(sign: S, magnitude: M) -> [Float] where S.Iterator.Element == Float, M.Iterator.Element == Float { +/// - Warning: does not support memory stride (assumes stride is 1). +public func copysign(sign: S, magnitude: M) -> [Float] where S.Element == Float, M.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(sign.count)) results.withUnsafeMutableBufferPointer { rbp in - withUnsafeBufferPointersTo(sign, magnitude) { sbp, mbp in - guard let sp = sbp.baseAddress, let mp = mbp.baseAddress else { - return - } - vvcopysignf(rbp.baseAddress!, mp, sp, [Int32(sbp.count)]) + withUnsafeMemory(sign, magnitude) { sm, mm in + precondition(sm.stride == 1 && mm.stride == 1, "\(#function) does not support strided memory access") + vvcopysignf(rbp.baseAddress!, mm.pointer, sm.pointer, [numericCast(sm.count)]) } } return results } -public func copysign(sign: S, magnitude: M) -> [Double] where S.Iterator.Element == Double, M.Iterator.Element == Double { +/// - Warning: does not support memory stride (assumes stride is 1). +public func copysign(sign: S, magnitude: M) -> [Double] where S.Element == Double, M.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(sign.count)) results.withUnsafeMutableBufferPointer { rbp in - withUnsafeBufferPointersTo(sign, magnitude) { sbp, mbp in - guard let sp = sbp.baseAddress, let mp = mbp.baseAddress else { - return - } - vvcopysign(rbp.baseAddress!, mp, sp, [Int32(sbp.count)]) + withUnsafeMemory(sign, magnitude) { sm, mm in + precondition(sm.stride == 1 && mm.stride == 1, "\(#function) does not support strided memory access") + vvcopysign(rbp.baseAddress!, mm.pointer, sm.pointer, [numericCast(sm.count)]) } } return results @@ -142,27 +138,29 @@ public func copysign(sign: S, // MARK: Floor -public func floor(_ x: C) -> [Float] where C.Iterator.Element == Float { +/// Elemen-wise floor. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func floor(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvfloorf(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvfloorf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results } -public func floor(_ x: C) -> [Double] where C.Iterator.Element == Double { +/// Elemen-wise floor. +/// +/// - Warning: does not support memory stride (assumes stride is 1). +public func floor(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvfloor(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvfloor(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results @@ -170,27 +168,21 @@ public func floor(_ x: C) -> [Double] where C.Iterator. // MARK: Negate -public func neg(_ x: C) -> [Float] where C.Iterator.Element == Float { +public func neg(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vDSP_vneg(xp, 1, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + x.withUnsafeMemory { xm in + vDSP_vneg(xm.pointer, xm.stride, rbp.baseAddress!, 1, numericCast(xm.count)) } } return results } -public func neg(_ x: C) -> [Double] where C.Iterator.Element == Double { +public func neg(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vDSP_vnegD(xp, 1, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + x.withUnsafeMemory { xm in + vDSP_vnegD(xm.pointer, xm.stride, rbp.baseAddress!, 1, numericCast(xm.count)) } } return results @@ -198,27 +190,25 @@ public func neg(_ x: C) -> [Double] where C.Iterator.El // MARK: Reciprocal -public func rec(_ x: C) -> [Float] where C.Iterator.Element == Float { +/// - Warning: does not support memory stride (assumes stride is 1). +public func rec(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvrecf(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvrecf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results } -public func rec(_ x: C) -> [Double] where C.Iterator.Element == Double { +/// - Warning: does not support memory stride (assumes stride is 1). +public func rec(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvrec(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvrec(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results @@ -226,27 +216,25 @@ public func rec(_ x: C) -> [Double] where C.Iterator.El // MARK: Round -public func round(_ x: C) -> [Float] where C.Iterator.Element == Float { +/// - Warning: does not support memory stride (assumes stride is 1). +public func round(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvnintf(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvnintf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results } -public func round(_ x: C) -> [Double] where C.Iterator.Element == Double { +/// - Warning: does not support memory stride (assumes stride is 1). +public func round(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvnint(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvnint(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results @@ -254,32 +242,26 @@ public func round(_ x: C) -> [Double] where C.Iterator. // MARK: Threshold -public func threshold(_ x: C, low: Float) -> [Float] where C.Iterator.Element == Float { +public func threshold(_ x: C, low: Float) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } + x.withUnsafeMemory { xm in var y = low withUnsafePointer(to: &y) { y in - vDSP_vthr(xp, 1, y, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + vDSP_vthr(xm.pointer, xm.stride, y, rbp.baseAddress!, 1, numericCast(xm.count)) } } } return results } -public func threshold(_ x: C, low: Double) -> [Double] where C.Iterator.Element == Double { +public func threshold(_ x: C, low: Double) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } + x.withUnsafeMemory { xm in var y = low withUnsafePointer(to: &y) { y in - vDSP_vthrD(xp, 1, y, rbp.baseAddress!, 1, vDSP_Length(xbp.count)) + vDSP_vthrD(xm.pointer, xm.stride, y, rbp.baseAddress!, 1, numericCast(xm.count)) } } } @@ -288,27 +270,25 @@ public func threshold(_ x: C, low: Double) -> [Double] // MARK: Truncate -public func trunc(_ x: C) -> [Float] where C.Iterator.Element == Float { +/// - Warning: does not support memory stride (assumes stride is 1). +public func trunc(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvintf(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvintf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results } -public func trunc(_ x: C) -> [Double] where C.Iterator.Element == Double { +/// - Warning: does not support memory stride (assumes stride is 1). +public func trunc(_ x: C) -> [Double] where C.Element == Double { var results = [Double](repeating: 0.0, count: numericCast(x.count)) results.withUnsafeMutableBufferPointer { rbp in - x.withUnsafeBufferPointer { xbp in - guard let xp = xbp.baseAddress else { - return - } - vvint(rbp.baseAddress!, xp, [Int32(xbp.count)]) + x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + vvint(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } } return results diff --git a/Sources/Surge/ContinuousCollection.swift b/Sources/Surge/ContinuousCollection.swift deleted file mode 100644 index 7c94639..0000000 --- a/Sources/Surge/ContinuousCollection.swift +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © 2017 Alejandro Isaza -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE 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 -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 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 IN -// THE SOFTWARE. - -import Foundation - -/// A collection that has a C array representation: a continuous block of memory. -public protocol ContinuousCollection: Collection { - /// Calls a closure with a pointer to the array's contiguous storage. - /// - /// The pointer passed as an argument to `body` is valid only during the execution of - /// `withUnsafeBufferPointer(_:)`. Do not store or return the pointer for later use. - /// - /// - Parameter body: A closure with an `UnsafeBufferPointer` parameter that points to the contiguous storage for - /// the array. If `body` has a return value, that value is also used as the return value for the - /// `withUnsafeBufferPointer(_:)` method. The pointer argument is valid only for the duration of the method's - /// execution. - /// - Returns: The return value, if any, of the `body` closure parameter. - func withUnsafeBufferPointer(_ body: (UnsafeBufferPointer) throws -> R) rethrows -> R -} - -/// A mutable collection that has a C array representation: a continuous block of memory. -public protocol ContinuousMutableCollection: ContinuousCollection { - /// Calls the given closure with a pointer to the array's mutable contiguous storage. - /// - /// The pointer passed as an argument to `body` is valid only during the execution of - /// `withUnsafeMutableBufferPointer(_:)`. Do not store or return the pointer for later use. - /// - /// - Parameter body: A closure with an `UnsafeMutableBufferPointer` parameter that points to the contiguous - /// storage for the array. If `body` has a return value, that value is also used as the return value for the - /// `withUnsafeMutableBufferPointer(_:)` method. The pointer argument is valid only for the duration of the - /// method's execution. - /// - Returns: The return value, if any, of the `body` closure parameter. - mutating func withUnsafeMutableBufferPointer(_ body: (inout UnsafeMutableBufferPointer) throws -> R) rethrows -> R -} - -extension Array: ContinuousMutableCollection {} -extension ContiguousArray: ContinuousMutableCollection {} -extension ArraySlice: ContinuousMutableCollection {} diff --git a/Sources/Surge/Convolution.swift b/Sources/Surge/Convolution.swift index ade6c73..69de6d5 100644 --- a/Sources/Surge/Convolution.swift +++ b/Sources/Surge/Convolution.swift @@ -1,5 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) -// Copyright © 2015-2016 Remy Prechelt +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,16 +22,16 @@ import Accelerate // MARK: Convolution -// Convolution of a signal [x], with a kernel [k]. The signal must be at least as long as the kernel. -public func conv(_ x: X, _ k: K) -> [Float] where X.Iterator.Element == Float, K.Iterator.Element == Float { +/// Convolution of a signal [x], with a kernel [k]. The signal must be at least as long as the kernel. +public func conv(_ x: X, _ k: K) -> [Float] where X.Element == Float, K.Element == Float { precondition(x.count >= k.count, "Input vector [x] must have at least as many elements as the kernel, [k]") let resultSize = numericCast(x.count) + numericCast(k.count) - 1 var result = [Float](repeating: 0, count: resultSize) result.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(k) { kp, kc in - let kEnd = kp.advanced(by: kc - 1) - let xPad = repeatElement(0 as Float, count: kc - 1) + k.withUnsafeMemory { km in + let kEnd = km.pointer.advanced(by: km.count * km.stride - 1) + let xPad = repeatElement(0 as Float, count: km.count - 1) var xPadded = [Float]() xPadded.reserveCapacity(xPad.count + numericCast(x.count) + xPad.count) @@ -40,22 +39,22 @@ public func conv(_ x: X, _ k: xPadded.append(contentsOf: x) xPadded.append(contentsOf: xPad) - vDSP_conv(xPadded, 1, kEnd, -1, rbp.baseAddress!, 1, vDSP_Length(resultSize), vDSP_Length(kc)) + vDSP_conv(xPadded, 1, kEnd, -km.stride, rbp.baseAddress!, 1, numericCast(resultSize), numericCast(km.count)) } } return result } -// Convolution of a signal [x], with a kernel [k]. The signal must be at least as long as the kernel. -public func conv(_ x: X, _ k: K) -> [Double] where X.Iterator.Element == Double, K.Iterator.Element == Double { +/// Convolution of a signal [x], with a kernel [k]. The signal must be at least as long as the kernel. +public func conv(_ x: X, _ k: K) -> [Double] where X.Element == Double, K.Element == Double { precondition(x.count >= k.count, "Input vector [x] must have at least as many elements as the kernel, [k]") let resultSize = numericCast(x.count) + numericCast(k.count) - 1 var result = [Double](repeating: 0, count: resultSize) result.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(k) { kp, kc in - let kEnd = kp.advanced(by: kc - 1) - let xPad = repeatElement(0 as Double, count: kc - 1) + k.withUnsafeMemory { km in + let kEnd = km.pointer.advanced(by: km.count * km.stride - 1) + let xPad = repeatElement(0 as Double, count: km.count - 1) var xPadded = [Double]() xPadded.reserveCapacity(xPad.count + numericCast(x.count) + xPad.count) @@ -63,7 +62,7 @@ public func conv(_ x: X, _ k: xPadded.append(contentsOf: x) xPadded.append(contentsOf: xPad) - vDSP_convD(xPadded, 1, kEnd, -1, rbp.baseAddress!, 1, vDSP_Length(resultSize), vDSP_Length(kc)) + vDSP_convD(xPadded, 1, kEnd, -km.stride, rbp.baseAddress!, 1, numericCast(resultSize), numericCast(km.count)) } } return result @@ -71,9 +70,9 @@ public func conv(_ x: X, _ k: // MARK: Cross-Correlation -// Cross-correlation of a signal [x], with another signal [y]. The signal [y] -// is padded so that it is the same length as [x]. -public func xcorr(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { +/// Cross-correlation of a signal [x], with another signal [y]. The signal [y] +/// is padded so that it is the same length as [x]. +public func xcorr(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { precondition(x.count >= y.count, "Input vector [x] must have at least as many elements as [y]") var yPadded = [Float](y) if x.count > y.count { @@ -92,15 +91,15 @@ public func xcorr(_ x: X, _ y: xPadded.append(contentsOf: xPad) result.withUnsafeMutableBufferPointer { rbp in - vDSP_conv(xPadded, 1, yPadded, 1, rbp.baseAddress!, 1, vDSP_Length(resultSize), vDSP_Length(yPadded.count)) + vDSP_conv(xPadded, 1, yPadded, 1, rbp.baseAddress!, 1, numericCast(resultSize), numericCast(yPadded.count)) } return result } -// Cross-correlation of a signal [x], with another signal [y]. The signal [y] -// is padded so that it is the same length as [x]. -public func xcorr(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { +/// Cross-correlation of a signal [x], with another signal [y]. The signal [y] +/// is padded so that it is the same length as [x]. +public func xcorr(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { precondition(x.count >= y.count, "Input vector [x] must have at least as many elements as [y]") var yPadded = [Double](y) if x.count > y.count { @@ -119,7 +118,7 @@ public func xcorr(_ x: X, _ y: xPadded.append(contentsOf: xPad) result.withUnsafeMutableBufferPointer { rbp in - vDSP_convD(xPadded, 1, yPadded, 1, rbp.baseAddress!, 1, vDSP_Length(resultSize), vDSP_Length(yPadded.count)) + vDSP_convD(xPadded, 1, yPadded, 1, rbp.baseAddress!, 1, numericCast(resultSize), numericCast(yPadded.count)) } return result @@ -127,8 +126,8 @@ public func xcorr(_ x: X, _ y: // MARK: Auto-correlation -// Auto-correlation of a signal [x] -public func xcorr(_ x: X) -> [Float] where X.Iterator.Element == Float { +/// Auto-correlation of a signal [x] +public func xcorr(_ x: X) -> [Float] where X.Element == Float { let resultSize = 2*numericCast(x.count) - 1 var result = [Float](repeating: 0, count: resultSize) let xPad = repeatElement(0 as Float, count: numericCast(x.count) - 1) @@ -139,17 +138,17 @@ public func xcorr(_ x: X) -> [Float] where X.Iterator.E xPadded.append(contentsOf: x) xPadded.append(contentsOf: xPad) - withUnsafePointersAndCountsTo(x) { xp, xc in + x.withUnsafeMemory { xm in result.withUnsafeMutableBufferPointer { rbp in - vDSP_conv(xPadded, 1, xp, 1, rbp.baseAddress!, 1, vDSP_Length(resultSize), vDSP_Length(xc)) + vDSP_conv(xPadded, 1, xm.pointer, xm.stride, rbp.baseAddress!, 1, numericCast(resultSize), numericCast(xm.count)) } } return result } -// Auto-correlation of a signal [x] -public func xcorr(_ x: X) -> [Double] where X.Iterator.Element == Double { +/// Auto-correlation of a signal [x] +public func xcorr(_ x: X) -> [Double] where X.Element == Double { let resultSize = 2*numericCast(x.count) - 1 var result = [Double](repeating: 0, count: resultSize) let xPad = repeatElement(0 as Double, count: numericCast(x.count) - 1) @@ -160,9 +159,9 @@ public func xcorr(_ x: X) -> [Double] where X.Iterator. xPadded.append(contentsOf: x) xPadded.append(contentsOf: xPad) - withUnsafePointersAndCountsTo(x) { xp, xc in + x.withUnsafeMemory { xm in result.withUnsafeMutableBufferPointer { rbp in - vDSP_convD(xPadded, 1, xp, 1, rbp.baseAddress!, 1, vDSP_Length(resultSize), vDSP_Length(xc)) + vDSP_convD(xPadded, 1, xm.pointer, xm.stride, rbp.baseAddress!, 1, numericCast(resultSize), numericCast(xm.count)) } } diff --git a/Sources/Surge/Exponential.swift b/Sources/Surge/Exponential.swift index 3c5834c..6bc92e7 100644 --- a/Sources/Surge/Exponential.swift +++ b/Sources/Surge/Exponential.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,132 +22,156 @@ import Accelerate // MARK: Exponentiation -public func exp(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvexpf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexpf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func exp(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvexp(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexp(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Square Exponentiation -public func exp2(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvexp2f(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp2(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexp2f(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func exp2(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvexp2(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp2(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexp2(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Natural Logarithm -public func log(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlogf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func log(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlogf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func log(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlog(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func log(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlog(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Base-2 Logarithm -public func log2(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlog2f(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func log2(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlog2f(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func log2(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlog2(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func log2(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlog2(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Base-10 Logarithm -public func log10(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlog10f(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func log10(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlog10f(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func log10(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlog10(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func log10(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlog10(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Logarithmic Exponentiation -public func logb(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlogbf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func logb(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlogbf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func logb(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](x) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvlogb(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func logb(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](x) + results.withUnsafeMutableBufferPointer { rbp in + vvlogb(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } diff --git a/Sources/Surge/FFT.swift b/Sources/Surge/FFT.swift index e1d6e54..6c09b84 100644 --- a/Sources/Surge/FFT.swift +++ b/Sources/Surge/FFT.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Sources/Surge/Hyperbolic.swift b/Sources/Surge/Hyperbolic.swift index 7498c89..30bbca1 100644 --- a/Sources/Surge/Hyperbolic.swift +++ b/Sources/Surge/Hyperbolic.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,144 +22,156 @@ import Accelerate // MARK: Hyperbolic Sine -public func sinh(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvsinhf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func sinh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvsinhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } -public func sinh(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvsinh(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func sinh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvsinh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } // MARK: Hyperbolic Cosine -public func cosh(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvcoshf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func cosh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvcoshf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } -public func cosh(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvcosh(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func cosh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvcosh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } // MARK: Hyperbolic Tangent -public func tanh(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvtanhf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func tanh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvtanhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } -public func tanh(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvtanh(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func tanh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvtanh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } // MARK: Inverse Hyperbolic Sine -public func asinh(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvasinhf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func asinh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvasinhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } -public func asinh(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvasinh(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func asinh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvasinh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } // MARK: Inverse Hyperbolic Cosine -public func acosh(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvacoshf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func acosh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvacoshf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } -public func acosh(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvacosh(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func acosh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvacosh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } // MARK: Inverse Hyperbolic Tangent -public func atanh(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvatanhf(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func atanh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvatanhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } -public func atanh(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvatanh(rbp.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func atanh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvatanh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - - return results } diff --git a/Sources/Surge/Matrix.swift b/Sources/Surge/Matrix.swift index 9d1bedf..3c02236 100644 --- a/Sources/Surge/Matrix.swift +++ b/Sources/Surge/Matrix.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -318,10 +318,10 @@ public func inv(_ x: Matrix) -> Matrix { var error: __CLPK_integer = 0 var nc = __CLPK_integer(x.columns) - withUnsafeMutableBufferPointersTo(&ipiv, &work, &(results.grid)) { ipiv, work, grid in - withUnsafeMutablePointersTo(&nc, &lwork, &error) { nc, lwork, error in - sgetrf_(nc, nc, grid.baseAddress!, nc, ipiv.baseAddress!, error) - sgetri_(nc, grid.baseAddress!, nc, ipiv.baseAddress!, work.baseAddress!, lwork, error) + withUnsafeMutablePointers(&nc, &lwork, &error) { nc, lwork, error in + withUnsafeMutableMemory(&ipiv, &work, &(results.grid)) { ipiv, work, grid in + sgetrf_(nc, nc, grid.pointer, nc, ipiv.pointer, error) + sgetri_(nc, grid.pointer, nc, ipiv.pointer, work.pointer, lwork, error) } } @@ -341,10 +341,10 @@ public func inv(_ x: Matrix) -> Matrix { var error: __CLPK_integer = 0 var nc = __CLPK_integer(x.columns) - withUnsafeMutableBufferPointersTo(&ipiv, &work, &(results.grid)) { ipiv, work, grid in - withUnsafeMutablePointersTo(&nc, &lwork, &error) { nc, lwork, error in - dgetrf_(nc, nc, grid.baseAddress!, nc, ipiv.baseAddress!, error) - dgetri_(nc, grid.baseAddress!, nc, ipiv.baseAddress!, work.baseAddress!, lwork, error) + withUnsafeMutablePointers(&nc, &lwork, &error) { nc, lwork, error in + withUnsafeMutableMemory(&ipiv, &work, &(results.grid)) { ipiv, work, grid in + dgetrf_(nc, nc, grid.pointer, nc, ipiv.pointer, error) + dgetri_(nc, grid.pointer, nc, ipiv.pointer, work.pointer, lwork, error) } } @@ -378,9 +378,9 @@ public func det(_ x: Matrix) -> Float? { var info = __CLPK_integer() var m = __CLPK_integer(x.rows) var n = __CLPK_integer(x.columns) - withUnsafeMutableBufferPointersTo(&pivots, &(decomposed.grid)) { ipiv, grid in - withUnsafeMutablePointersTo(&m, &n, &info) { m, n, info in - sgetrf_(m, n, grid.baseAddress!, m, ipiv.baseAddress!, info) + _ = withUnsafeMutableMemory(&pivots, &(decomposed.grid)) { ipiv, grid in + withUnsafeMutablePointers(&m, &n, &info) { m, n, info in + sgetrf_(m, n, grid.pointer, m, ipiv.pointer, info) } } @@ -406,9 +406,9 @@ public func det(_ x: Matrix) -> Double? { var info = __CLPK_integer() var m = __CLPK_integer(x.rows) var n = __CLPK_integer(x.columns) - withUnsafeMutableBufferPointersTo(&pivots, &(decomposed.grid)) { ipiv, grid in - withUnsafeMutablePointersTo(&m, &n, &info) { m, n, info in - dgetrf_(m, n, grid.baseAddress!, m, ipiv.baseAddress!, info) + _ = withUnsafeMutableMemory(&pivots, &(decomposed.grid)) { ipiv, grid in + withUnsafeMutablePointers(&m, &n, &info) { m, n, info in + dgetrf_(m, n, grid.pointer, m, ipiv.pointer, info) } } diff --git a/Sources/Surge/Pointers.swift b/Sources/Surge/Pointers.swift index 5aba529..9e27a87 100644 --- a/Sources/Surge/Pointers.swift +++ b/Sources/Surge/Pointers.swift @@ -1,4 +1,4 @@ -// Copyright © 2017 Alejandro Isaza +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -18,47 +18,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -// MARK: 1 Parameter - -/// Invokes the given closure with buffer pointers to the given arrays (1 parameter version). -/// -/// - See: `Array.withUnsafeBufferPointer(_:)` -@discardableResult -public func withUnsafeBufferPointersTo(_ a: A, body: (UnsafeBufferPointer) throws -> Result) rethrows -> Result { - return try a.withUnsafeBufferPointer { (a: UnsafeBufferPointer) throws -> Result in - try body(a) - } -} - -/// Invokes the given closure with pointers to the given arrays (1 parameter version). -/// -/// - See: `Array.withUnsafeBufferPointer(_:)` -public func withUnsafePointersAndCountsTo(_ a: A, body: (UnsafePointer, Int) throws -> Void) rethrows { - try a.withUnsafeBufferPointer { (a: UnsafeBufferPointer) throws -> Void in - if let ab = a.baseAddress { - try body(ab, a.count) - } - } -} - -/// Invokes the given closure with mutable pointers to the given arrays (1 parameter version). -/// -/// - See: `Array.withUnsafeMutableBufferPointer(_:)` -public func withUnsafeMutablePointersAndCountsTo(_ a: inout A, body: (UnsafeMutablePointer, Int) throws -> Void) rethrows { - try a.withUnsafeMutableBufferPointer { (a: inout UnsafeMutableBufferPointer) throws -> Void in - if let ab = a.baseAddress { - try body(ab, a.count) - } - } -} - // MARK: 2 Parameter /// Invokes the given closure with pointers to the given arguments (2 parameter version). /// /// - See: `withUnsafePointer(to:body:)` @discardableResult -public func withUnsafePointersTo(_ a: inout A, _ b: inout B, body: (UnsafePointer, UnsafePointer) throws -> Result) rethrows -> Result { +public func withUnsafePointers(_ a: inout A, _ b: inout B, body: (UnsafePointer, UnsafePointer) throws -> Result) rethrows -> Result { return try withUnsafePointer(to: &a) { (a: UnsafePointer) throws -> Result in return try withUnsafePointer(to: &b) { (b: UnsafePointer) throws -> Result in return try body(a, b) @@ -70,7 +36,7 @@ public func withUnsafePointersTo(_ a: inout A, _ b: inout B, body: /// /// - See: `withUnsafeMutablePointer(to:body:)` @discardableResult -public func withUnsafeMutablePointersTo(_ a: inout A, _ b: inout B, body: (UnsafeMutablePointer, UnsafeMutablePointer) throws -> Result) rethrows -> Result { +public func withUnsafeMutablePointers(_ a: inout A, _ b: inout B, body: (UnsafeMutablePointer, UnsafeMutablePointer) throws -> Result) rethrows -> Result { return try withUnsafeMutablePointer(to: &a) { (a: UnsafeMutablePointer) throws -> Result in return try withUnsafeMutablePointer(to: &b) { (b: UnsafeMutablePointer) throws -> Result in return try body(a, b) @@ -78,63 +44,13 @@ public func withUnsafeMutablePointersTo(_ a: inout A, _ b: inout B } } -/// Invokes the given closure with pointers to the given arrays (2 parameter version). -/// -/// - See: `Array.withUnsafeBufferPointer(_:)` -@discardableResult -public func withUnsafeBufferPointersTo(_ a: A, _ b: B, body: (UnsafeBufferPointer, UnsafeBufferPointer) throws -> Result) rethrows -> Result { - return try a.withUnsafeBufferPointer { (a: UnsafeBufferPointer) throws -> Result in - try b.withUnsafeBufferPointer { (b: UnsafeBufferPointer) throws -> Result in - try body(a, b) - } - } -} - -/// Invokes the given closure with mutable pointers to the given arrays (2 parameter version). -/// -/// - See: `Array.withUnsafeMutableBufferPointer(_:)` -@discardableResult -public func withUnsafeMutableBufferPointersTo(_ a: inout A, _ b: inout B, body: (UnsafeMutableBufferPointer, UnsafeMutableBufferPointer) throws -> Result) rethrows -> Result { - return try a.withUnsafeMutableBufferPointer { (a: inout UnsafeMutableBufferPointer) throws -> Result in - try b.withUnsafeMutableBufferPointer { (b: inout UnsafeMutableBufferPointer) throws -> Result in - try body(a, b) - } - } -} - -/// Invokes the given closure with pointers to the given arrays (2 parameter version). -/// -/// - See: `Array.withUnsafeBufferPointer(_:)` -public func withUnsafePointersAndCountsTo(_ a: A, _ b: B, body: (UnsafePointer, Int, UnsafePointer, Int) throws -> Void) rethrows { - try a.withUnsafeBufferPointer { (a: UnsafeBufferPointer) throws -> Void in - try b.withUnsafeBufferPointer { (b: UnsafeBufferPointer) throws -> Void in - if let ab = a.baseAddress, let bb = b.baseAddress { - try body(ab, a.count, bb, b.count) - } - } - } -} - -/// Invokes the given closure with mutable pointers to the given arrays (2 parameter version). -/// -/// - See: `Array.withUnsafeMutableBufferPointer(_:)` -public func withUnsafeMutablePointersAndCountsTo(_ a: inout A, _ b: inout B, body: (UnsafeMutablePointer, Int, UnsafeMutablePointer, Int) throws -> Void) rethrows { - try a.withUnsafeMutableBufferPointer { (a: inout UnsafeMutableBufferPointer) throws -> Void in - try b.withUnsafeMutableBufferPointer { (b: inout UnsafeMutableBufferPointer) throws -> Void in - if let ab = a.baseAddress, let bb = b.baseAddress { - try body(ab, a.count, bb, b.count) - } - } - } -} - // MARK: 3 Parameter /// Invokes the given closure with pointers to the given arguments (3 parameter version). /// /// - See: `withUnsafePointer(to:body:)` @discardableResult -public func withUnsafePointersTo(_ a: inout A, _ b: inout B, _ c: inout C, body: (UnsafePointer, UnsafePointer, UnsafePointer) throws -> Result) rethrows -> Result { +public func withUnsafePointers(_ a: inout A, _ b: inout B, _ c: inout C, body: (UnsafePointer, UnsafePointer, UnsafePointer) throws -> Result) rethrows -> Result { return try withUnsafePointer(to: &a) { (a: UnsafePointer) throws -> Result in return try withUnsafePointer(to: &b) { (b: UnsafePointer) throws -> Result in return try withUnsafePointer(to: &c) { (c: UnsafePointer) throws -> Result in @@ -148,7 +64,7 @@ public func withUnsafePointersTo(_ a: inout A, _ b: inout B, _ /// /// - See: `withUnsafeMutablePointer(to:body:)` @discardableResult -public func withUnsafeMutablePointersTo(_ a: inout A, _ b: inout B, _ c: inout C, body: (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) throws -> Result) rethrows -> Result { +public func withUnsafeMutablePointers(_ a: inout A, _ b: inout B, _ c: inout C, body: (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) throws -> Result) rethrows -> Result { return try withUnsafeMutablePointer(to: &a) { (a: UnsafeMutablePointer) throws -> Result in return try withUnsafeMutablePointer(to: &b) { (b: UnsafeMutablePointer) throws -> Result in return try withUnsafeMutablePointer(to: &c) { (c: UnsafeMutablePointer) throws -> Result in @@ -157,31 +73,3 @@ public func withUnsafeMutablePointersTo(_ a: inout A, _ b: inou } } } - -/// Invokes the given closure with pointers to the given arrays (3 parameter version). -/// -/// - See: `Array.withUnsafeBufferPointer(_:)` -@discardableResult -public func withUnsafeBufferPointersTo(_ a: A, _ b: B, _ c: inout C, body: (UnsafeBufferPointer, UnsafeBufferPointer, UnsafeBufferPointer) throws -> Result) rethrows -> Result { - return try a.withUnsafeBufferPointer { (a: UnsafeBufferPointer) throws -> Result in - try b.withUnsafeBufferPointer { (b: UnsafeBufferPointer) throws -> Result in - try c.withUnsafeBufferPointer { (c: UnsafeBufferPointer) throws -> Result in - try body(a, b, c) - } - } - } -} - -/// Invokes the given closure with mutable pointers to the given arrays (3 parameter version). -/// -/// - See: `Array.withUnsafeMutableBufferPointer(_:)` -@discardableResult -public func withUnsafeMutableBufferPointersTo(_ a: inout A, _ b: inout B, _ c: inout C, body: (UnsafeMutableBufferPointer, UnsafeMutableBufferPointer, UnsafeMutableBufferPointer) throws -> Result) rethrows -> Result { - return try a.withUnsafeMutableBufferPointer { (a: inout UnsafeMutableBufferPointer) throws -> Result in - try b.withUnsafeMutableBufferPointer { (b: inout UnsafeMutableBufferPointer) throws -> Result in - try c.withUnsafeMutableBufferPointer { (c: inout UnsafeMutableBufferPointer) throws -> Result in - try body(a, b, c) - } - } - } -} diff --git a/Sources/Surge/Power.swift b/Sources/Surge/Power.swift index 632440a..ab94acb 100644 --- a/Sources/Surge/Power.swift +++ b/Sources/Surge/Power.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,32 +22,36 @@ import Accelerate // MARK: Power -public func pow(_ x: X, _ y: Y) -> [Float] where X.Iterator.Element == Float, Y.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x, y) { xp, xc, yp, _ in - vvpowf(pointer.baseAddress!, xp, yp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func pow(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvpowf(pointer.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func pow(_ x: X, _ y: Y) -> [Double] where X.Iterator.Element == Double, Y.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x, y) { xp, xc, yp, _ in - vvpow(pointer.baseAddress!, xp, yp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func pow(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { + return withUnsafeMemory(x, y) { xm, ym in + precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvpow(pointer.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func pow(_ x: X, _ y: Float) -> [Float] where X.Iterator.Element == Float { +public func pow(_ x: X, _ y: Float) -> [Float] where X.Element == Float { let yVec = [Float](repeating: y, count: numericCast(x.count)) return pow(yVec, x) } -public func pow(_ x: X, _ y: Double) -> [Double] where X.Iterator.Element == Double { +public func pow(_ x: X, _ y: Double) -> [Double] where X.Element == Double { let yVec = [Double](repeating: y, count: numericCast(x.count)) return pow(yVec, x) } diff --git a/Sources/Surge/Surge.h b/Sources/Surge/Surge.h index 7263fc6..1683ece 100644 --- a/Sources/Surge/Surge.h +++ b/Sources/Surge/Surge.h @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Sources/Surge/Trigonometric.swift b/Sources/Surge/Trigonometric.swift index 9be70fe..f18f57f 100644 --- a/Sources/Surge/Trigonometric.swift +++ b/Sources/Surge/Trigonometric.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,206 +22,242 @@ import Accelerate // MARK: Sine-Cosine -public func sincos(_ x: X) -> (sin: [Float], cos: [Float]) where X.Iterator.Element == Float { - var sin = [Float](repeating: 0.0, count: numericCast(x.count)) - var cos = [Float](repeating: 0.0, count: numericCast(x.count)) - withUnsafeMutableBufferPointersTo(&sin, &cos) { sin, cos in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvsincosf(sin.baseAddress!, cos.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func sincos(_ x: X) -> (sin: [Float], cos: [Float]) where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var sin = [Float](repeating: 0.0, count: numericCast(xm.count)) + var cos = [Float](repeating: 0.0, count: numericCast(xm.count)) + withUnsafeMutableMemory(&sin, &cos) { sinm, cosm in + vvsincosf(sinm.pointer, cosm.pointer, xm.pointer, [numericCast(xm.count)]) } + return (sin, cos) } - return (sin, cos) } -public func sincos(_ x: X) -> (sin: [Double], cos: [Double]) where X.Iterator.Element == Double { - var sin = [Double](repeating: 0.0, count: numericCast(x.count)) - var cos = [Double](repeating: 0.0, count: numericCast(x.count)) - withUnsafeMutableBufferPointersTo(&sin, &cos) { sin, cos in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvsincos(sin.baseAddress!, cos.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func sincos(_ x: X) -> (sin: [Double], cos: [Double]) where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var sin = [Double](repeating: 0.0, count: numericCast(xm.count)) + var cos = [Double](repeating: 0.0, count: numericCast(xm.count)) + withUnsafeMutableMemory(&sin, &cos) { sinm, cosm in + vvsincos(sinm.pointer, cosm.pointer, xm.pointer, [numericCast(xm.count)]) } + return (sin, cos) } - return (sin, cos) } // MARK: Sine -public func sin(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvsinf(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func sin(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvsinf(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func sin(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvsin(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func sin(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvsin(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Cosine -public func cos(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvcosf(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func cos(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvcosf(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func cos(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvcos(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func cos(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvcos(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Tangent -public func tan(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvtanf(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func tan(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvtanf(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func tan(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvtan(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func tan(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvtan(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Arcsine -public func asin(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvasinf(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func asin(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvasinf(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func asin(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvasin(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func asin(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvasin(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Arccosine -public func acos(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvacosf(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func acos(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvacosf(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func acos(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvacos(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func acos(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvacos(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: Arctangent -public func atan(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvatanf(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func atan(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvatanf(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } -public func atan(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvatan(pointer.baseAddress!, xp, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +public func atan(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvatan(pointer.baseAddress!, xm.pointer, [numericCast(xm.count)]) } + return results } - return results } // MARK: - // MARK: Radians to Degrees -func rad2deg(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - let divisor = [Float](repeating: Float.pi / 180.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvdivf(pointer.baseAddress!, xp, divisor, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +func rad2deg(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + let divisor = [Float](repeating: Float.pi / 180.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvdivf(pointer.baseAddress!, xm.pointer, divisor, [numericCast(xm.count)]) } + return results } - return results } -func rad2deg(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - let divisor = [Double](repeating: Double.pi / 180.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvdiv(pointer.baseAddress!, xp, divisor, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +func rad2deg(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + let divisor = [Double](repeating: Double.pi / 180.0, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvdiv(pointer.baseAddress!, xm.pointer, divisor, [numericCast(xm.count)]) } + return results } - return results } // MARK: Degrees to Radians -func deg2rad(_ x: X) -> [Float] where X.Iterator.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - let divisor = [Float](repeating: 180.0 / Float.pi, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvdivf(pointer.baseAddress!, xp, divisor, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +func deg2rad(_ x: X) -> [Float] where X.Element == Float { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(xm.count)) + let divisor = [Float](repeating: 180.0 / Float.pi, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvdivf(pointer.baseAddress!, xm.pointer, divisor, [numericCast(xm.count)]) } + return results } - return results } -func deg2rad(_ x: X) -> [Double] where X.Iterator.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - let divisor = [Double](repeating: 180.0 / Double.pi, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { pointer in - withUnsafePointersAndCountsTo(x) { xp, xc in - vvdiv(pointer.baseAddress!, xp, divisor, [Int32(xc)]) +/// - Warning: does not support memory stride (assumes stride is 1). +func deg2rad(_ x: X) -> [Double] where X.Element == Double { + return withUnsafeMemory(x) { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(xm.count)) + let divisor = [Double](repeating: 180.0 / Double.pi, count: numericCast(xm.count)) + results.withUnsafeMutableBufferPointer { pointer in + vvdiv(pointer.baseAddress!, xm.pointer, divisor, [numericCast(xm.count)]) } + return results } - return results } diff --git a/Sources/Surge/UnsafeMemory.swift b/Sources/Surge/UnsafeMemory.swift new file mode 100644 index 0000000..9129751 --- /dev/null +++ b/Sources/Surge/UnsafeMemory.swift @@ -0,0 +1,79 @@ +// Copyright © 2014-2018 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 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 IN +// THE SOFTWARE. + +import Foundation + +/// Memory region. +public struct UnsafeMemory: Sequence { + /// Pointer to the first element + public var pointer: UnsafePointer + + /// Pointer stride between elements + public var stride: Int + + /// Number of elements + public var count: Int + + public func makeIterator() -> UnsafeMemoryIterator { + return UnsafeMemoryIterator(self) + } +} + +public struct UnsafeMemoryIterator: IteratorProtocol { + let base: UnsafeMemory + var index: Int? + + public init(_ base: UnsafeMemory) { + self.base = base + } + + public mutating func next() -> Element? { + let newIndex: Int + if let index = index { + newIndex = index + 1 + } else { + newIndex = 0 + } + + if newIndex >= base.count { + return nil + } + + self.index = newIndex + return base.pointer[newIndex * base.stride] + } +} + +/// Protocol for collections that can be accessed via `UnsafeMemory` +public protocol UnsafeMemoryAccessible: Collection { + func withUnsafeMemory(_ body: (UnsafeMemory) throws -> Result) rethrows -> Result +} + +public func withUnsafeMemory(_ x: X, _ body: (UnsafeMemory) throws -> Result) rethrows -> Result { + return try x.withUnsafeMemory(body) +} + +public func withUnsafeMemory(_ x: X, _ y: Y, _ body: (UnsafeMemory, UnsafeMemory) throws -> Result) rethrows -> Result { + return try x.withUnsafeMemory { xm in + try y.withUnsafeMemory { ym in + try body(xm, ym) + } + } +} diff --git a/Sources/Surge/UnsafeMutableMemory.swift b/Sources/Surge/UnsafeMutableMemory.swift new file mode 100644 index 0000000..f1c5563 --- /dev/null +++ b/Sources/Surge/UnsafeMutableMemory.swift @@ -0,0 +1,89 @@ +// Copyright © 2014-2018 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 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 IN +// THE SOFTWARE. + +import Foundation + +/// Mutable memory region. +public struct UnsafeMutableMemory { + /// Pointer to the first element + var pointer: UnsafeMutablePointer + + /// Pointer stride between elements + var stride: Int + + /// Number of elements + var count: Int + + public func makeIterator() -> UnsafeMutableMemoryIterator { + return UnsafeMutableMemoryIterator(self) + } +} + +public struct UnsafeMutableMemoryIterator: IteratorProtocol { + let base: UnsafeMutableMemory + var index: Int? + + public init(_ base: UnsafeMutableMemory) { + self.base = base + } + + public mutating func next() -> Element? { + let newIndex: Int + if let index = index { + newIndex = index + 1 + } else { + newIndex = 0 + } + + if newIndex >= base.count { + return nil + } + + self.index = newIndex + return base.pointer[newIndex * base.stride] + } +} + +/// Protocol for mutable collections that can be accessed via `UnsafeMutableMemory` +public protocol UnsafeMutableMemoryAccessible: UnsafeMemoryAccessible { + mutating func withUnsafeMutableMemory(_ body: (UnsafeMutableMemory) throws -> Result) rethrows -> Result +} + +public func withUnsafeMutableMemory(_ x: inout X, _ body: (UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try x.withUnsafeMutableMemory(body) +} + +public func withUnsafeMutableMemory(_ x: inout X, _ y: inout Y, _ body: (UnsafeMutableMemory, UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try x.withUnsafeMutableMemory { xm in + try y.withUnsafeMutableMemory { ym in + try body(xm, ym) + } + } +} + +public func withUnsafeMutableMemory(_ x: inout X, _ y: inout Y, _ z: inout Z, _ body: (UnsafeMutableMemory, UnsafeMutableMemory, UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try x.withUnsafeMutableMemory { xm in + try y.withUnsafeMutableMemory { ym in + try z.withUnsafeMutableMemory { zm in + try body(xm, ym, zm) + } + } + } +} diff --git a/Surge.playground/Contents.swift b/Surge.playground/Contents.swift index 6141296..14ffa8b 100644 --- a/Surge.playground/Contents.swift +++ b/Surge.playground/Contents.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ let sum = Surge.sum(n) let a = [1.0, 3.0, 5.0, 7.0] let b = [2.0, 4.0, 6.0, 8.0] -let product = Surge.mul(a, y: b) +let product = mul(a, b) // MARK: - Matrix diff --git a/Surge.xcodeproj/project.pbxproj b/Surge.xcodeproj/project.pbxproj index 95d5b95..de79b61 100644 --- a/Surge.xcodeproj/project.pbxproj +++ b/Surge.xcodeproj/project.pbxproj @@ -19,7 +19,6 @@ 614AD33F1FC0AF72002BFE1C /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 614AD3401FC0AF72002BFE1C /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; 614AD3411FC0AF72002BFE1C /* Trigonometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394551F762B58002A4AD2 /* Trigonometric.swift */; }; - 614AD3421FC0AF72002BFE1C /* ContinuousCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394E31F76D3ED002A4AD2 /* ContinuousCollection.swift */; }; 614AD3431FC0AF77002BFE1C /* ArithmeticTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6D1F70D22600B99FFB /* ArithmeticTests.swift */; }; 614AD3441FC0AF77002BFE1C /* AuxiliaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6E1F70D22600B99FFB /* AuxiliaryTests.swift */; }; 614AD3451FC0AF77002BFE1C /* ConvolutionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6F1F70D22600B99FFB /* ConvolutionTests.swift */; }; @@ -41,7 +40,6 @@ 614AD3701FC0B0CC002BFE1C /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 614AD3711FC0B0CC002BFE1C /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; 614AD3721FC0B0CC002BFE1C /* Trigonometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394551F762B58002A4AD2 /* Trigonometric.swift */; }; - 614AD3731FC0B0CC002BFE1C /* ContinuousCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394E31F76D3ED002A4AD2 /* ContinuousCollection.swift */; }; 614AD3741FC0B0D2002BFE1C /* ArithmeticTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6D1F70D22600B99FFB /* ArithmeticTests.swift */; }; 614AD3751FC0B0D2002BFE1C /* AuxiliaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6E1F70D22600B99FFB /* AuxiliaryTests.swift */; }; 614AD3761FC0B0D2002BFE1C /* ConvolutionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6F1F70D22600B99FFB /* ConvolutionTests.swift */; }; @@ -62,7 +60,6 @@ 614AD3921FC0B134002BFE1C /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 614AD3931FC0B134002BFE1C /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; 614AD3941FC0B134002BFE1C /* Trigonometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394551F762B58002A4AD2 /* Trigonometric.swift */; }; - 614AD3951FC0B134002BFE1C /* ContinuousCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394E31F76D3ED002A4AD2 /* ContinuousCollection.swift */; }; 615394561F762B59002A4AD2 /* Arithmetic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944B1F762B58002A4AD2 /* Arithmetic.swift */; }; 615394571F762B59002A4AD2 /* Auxiliary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944C1F762B58002A4AD2 /* Auxiliary.swift */; }; 615394581F762B59002A4AD2 /* Convolution.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944D1F762B58002A4AD2 /* Convolution.swift */; }; @@ -74,7 +71,6 @@ 6153945E1F762B59002A4AD2 /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; 6153945F1F762B59002A4AD2 /* Surge.h in Headers */ = {isa = PBXBuildFile; fileRef = 615394541F762B58002A4AD2 /* Surge.h */; settings = {ATTRIBUTES = (Public, ); }; }; 615394601F762B59002A4AD2 /* Trigonometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394551F762B58002A4AD2 /* Trigonometric.swift */; }; - 615394E41F76D3ED002A4AD2 /* ContinuousCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394E31F76D3ED002A4AD2 /* ContinuousCollection.swift */; }; 61A0AD761F70D22600B99FFB /* ArithmeticTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6D1F70D22600B99FFB /* ArithmeticTests.swift */; }; 61A0AD771F70D22600B99FFB /* AuxiliaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6E1F70D22600B99FFB /* AuxiliaryTests.swift */; }; 61A0AD781F70D22600B99FFB /* ConvolutionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD6F1F70D22600B99FFB /* ConvolutionTests.swift */; }; @@ -84,6 +80,22 @@ 61A0AD7C1F70D22600B99FFB /* PowerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD731F70D22600B99FFB /* PowerTests.swift */; }; 61A0AD7D1F70D22600B99FFB /* TrigonometricTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD741F70D22600B99FFB /* TrigonometricTests.swift */; }; 61A0AD7E1F70D22600B99FFB /* XCTestCase+Surge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0AD751F70D22600B99FFB /* XCTestCase+Surge.swift */; }; + 61E930B8207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; + 61E930B9207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; + 61E930BA207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; + 61E930BB207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; + 61E930BD2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; + 61E930BE2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; + 61E930BF2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; + 61E930C02070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; + 61E930C22070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; + 61E930C32070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; + 61E930C42070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; + 61E930C52070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; + 61E930C82070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; + 61E930C92070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; + 61E930CA2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; + 61E930CB2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; F8A1E1D519917C25009735E2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8A1E1D219917C0B009735E2 /* Accelerate.framework */; }; F8A1E1D719917C2B009735E2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8A1E1D619917C2B009735E2 /* Foundation.framework */; }; /* End PBXBuildFile section */ @@ -132,7 +144,6 @@ 615394531F762B58002A4AD2 /* Power.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Power.swift; sourceTree = ""; }; 615394541F762B58002A4AD2 /* Surge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Surge.h; sourceTree = ""; }; 615394551F762B58002A4AD2 /* Trigonometric.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Trigonometric.swift; sourceTree = ""; }; - 615394E31F76D3ED002A4AD2 /* ContinuousCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContinuousCollection.swift; sourceTree = ""; }; 61A0AD6D1F70D22600B99FFB /* ArithmeticTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArithmeticTests.swift; sourceTree = ""; }; 61A0AD6E1F70D22600B99FFB /* AuxiliaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuxiliaryTests.swift; sourceTree = ""; }; 61A0AD6F1F70D22600B99FFB /* ConvolutionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvolutionTests.swift; sourceTree = ""; }; @@ -145,6 +156,10 @@ 61A0AD7F1F70D99B00B99FFB /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 61A0AD801F70D99B00B99FFB /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 61A0AD811F70D99B00B99FFB /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 61E930B7207002EA00694FCB /* UnsafeMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsafeMemory.swift; sourceTree = ""; }; + 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayUnsafeMemory.swift; sourceTree = ""; }; + 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsafeMutableMemory.swift; sourceTree = ""; }; + 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArraySliceUnsafeMemory.swift; sourceTree = ""; }; F84A6AAE19A9A72F007B53E1 /* SurgeTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SurgeTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; F8A1E1AA19917A79009735E2 /* Surge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Surge.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F8A1E1D219917C0B009735E2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; @@ -221,6 +236,8 @@ children = ( 615394541F762B58002A4AD2 /* Surge.h */, 6153944B1F762B58002A4AD2 /* Arithmetic.swift */, + 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */, + 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */, 6153944C1F762B58002A4AD2 /* Auxiliary.swift */, 6153944D1F762B58002A4AD2 /* Convolution.swift */, 6153944E1F762B58002A4AD2 /* Exponential.swift */, @@ -230,7 +247,8 @@ 615394521F762B58002A4AD2 /* Pointers.swift */, 615394531F762B58002A4AD2 /* Power.swift */, 615394551F762B58002A4AD2 /* Trigonometric.swift */, - 615394E31F76D3ED002A4AD2 /* ContinuousCollection.swift */, + 61E930B7207002EA00694FCB /* UnsafeMemory.swift */, + 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */, ); path = Surge; sourceTree = ""; @@ -660,6 +678,8 @@ buildActionMask = 2147483647; files = ( 614AD33E1FC0AF72002BFE1C /* Matrix.swift in Sources */, + 61E930C32070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, + 61E930C92070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, 614AD3391FC0AF72002BFE1C /* Auxiliary.swift in Sources */, 614AD3411FC0AF72002BFE1C /* Trigonometric.swift in Sources */, 614AD3381FC0AF72002BFE1C /* Arithmetic.swift in Sources */, @@ -667,9 +687,10 @@ 614AD33A1FC0AF72002BFE1C /* Convolution.swift in Sources */, 614AD33F1FC0AF72002BFE1C /* Pointers.swift in Sources */, 614AD33C1FC0AF72002BFE1C /* FFT.swift in Sources */, + 61E930BE2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930B9207002EA00694FCB /* UnsafeMemory.swift in Sources */, 614AD3401FC0AF72002BFE1C /* Power.swift in Sources */, 614AD33B1FC0AF72002BFE1C /* Exponential.swift in Sources */, - 614AD3421FC0AF72002BFE1C /* ContinuousCollection.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -694,6 +715,8 @@ buildActionMask = 2147483647; files = ( 614AD36F1FC0B0CC002BFE1C /* Matrix.swift in Sources */, + 61E930C42070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, + 61E930CA2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, 614AD36A1FC0B0CC002BFE1C /* Auxiliary.swift in Sources */, 614AD3721FC0B0CC002BFE1C /* Trigonometric.swift in Sources */, 614AD3691FC0B0CC002BFE1C /* Arithmetic.swift in Sources */, @@ -701,9 +724,10 @@ 614AD36B1FC0B0CC002BFE1C /* Convolution.swift in Sources */, 614AD3701FC0B0CC002BFE1C /* Pointers.swift in Sources */, 614AD36D1FC0B0CC002BFE1C /* FFT.swift in Sources */, + 61E930BF2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930BA207002EA00694FCB /* UnsafeMemory.swift in Sources */, 614AD3711FC0B0CC002BFE1C /* Power.swift in Sources */, 614AD36C1FC0B0CC002BFE1C /* Exponential.swift in Sources */, - 614AD3731FC0B0CC002BFE1C /* ContinuousCollection.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -728,6 +752,8 @@ buildActionMask = 2147483647; files = ( 614AD3911FC0B134002BFE1C /* Matrix.swift in Sources */, + 61E930C52070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, + 61E930CB2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, 614AD38C1FC0B134002BFE1C /* Auxiliary.swift in Sources */, 614AD3941FC0B134002BFE1C /* Trigonometric.swift in Sources */, 614AD38B1FC0B134002BFE1C /* Arithmetic.swift in Sources */, @@ -735,9 +761,10 @@ 614AD38D1FC0B134002BFE1C /* Convolution.swift in Sources */, 614AD3921FC0B134002BFE1C /* Pointers.swift in Sources */, 614AD38F1FC0B134002BFE1C /* FFT.swift in Sources */, + 61E930C02070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930BB207002EA00694FCB /* UnsafeMemory.swift in Sources */, 614AD3931FC0B134002BFE1C /* Power.swift in Sources */, 614AD38E1FC0B134002BFE1C /* Exponential.swift in Sources */, - 614AD3951FC0B134002BFE1C /* ContinuousCollection.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -762,6 +789,8 @@ buildActionMask = 2147483647; files = ( 6153945C1F762B59002A4AD2 /* Matrix.swift in Sources */, + 61E930C22070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, + 61E930C82070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, 615394571F762B59002A4AD2 /* Auxiliary.swift in Sources */, 615394601F762B59002A4AD2 /* Trigonometric.swift in Sources */, 615394561F762B59002A4AD2 /* Arithmetic.swift in Sources */, @@ -769,9 +798,10 @@ 615394581F762B59002A4AD2 /* Convolution.swift in Sources */, 6153945D1F762B59002A4AD2 /* Pointers.swift in Sources */, 6153945A1F762B59002A4AD2 /* FFT.swift in Sources */, + 61E930BD2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930B8207002EA00694FCB /* UnsafeMemory.swift in Sources */, 6153945E1F762B59002A4AD2 /* Power.swift in Sources */, 615394591F762B59002A4AD2 /* Exponential.swift in Sources */, - 615394E41F76D3ED002A4AD2 /* ContinuousCollection.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Surge.xcodeproj/xcshareddata/xcschemes/Surge-iOS.xcscheme b/Surge.xcodeproj/xcshareddata/xcschemes/Surge-iOS.xcscheme index 23393e4..312d272 100644 --- a/Surge.xcodeproj/xcshareddata/xcschemes/Surge-iOS.xcscheme +++ b/Surge.xcodeproj/xcshareddata/xcschemes/Surge-iOS.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + codeCoverageEnabled = "YES" shouldUseLaunchSchemeArgsEnv = "YES"> - - + + diff --git a/Tests/SurgeTests/ArithmeticTests.swift b/Tests/SurgeTests/ArithmeticTests.swift index 52ab982..ce69a6d 100644 --- a/Tests/SurgeTests/ArithmeticTests.swift +++ b/Tests/SurgeTests/ArithmeticTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/AuxiliaryTests.swift b/Tests/SurgeTests/AuxiliaryTests.swift index 0eb9508..7d1e9a9 100644 --- a/Tests/SurgeTests/AuxiliaryTests.swift +++ b/Tests/SurgeTests/AuxiliaryTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/ConvolutionTests.swift b/Tests/SurgeTests/ConvolutionTests.swift index 439a97d..6eeebf1 100644 --- a/Tests/SurgeTests/ConvolutionTests.swift +++ b/Tests/SurgeTests/ConvolutionTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2016 Remy Prechelt, Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/ExponentialTests.swift b/Tests/SurgeTests/ExponentialTests.swift index f8d3872..6c782e2 100644 --- a/Tests/SurgeTests/ExponentialTests.swift +++ b/Tests/SurgeTests/ExponentialTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/HyperbolicTests.swift b/Tests/SurgeTests/HyperbolicTests.swift index ba598f8..8434dfa 100644 --- a/Tests/SurgeTests/HyperbolicTests.swift +++ b/Tests/SurgeTests/HyperbolicTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/MatrixTests.swift b/Tests/SurgeTests/MatrixTests.swift index 0935105..e57ac28 100644 --- a/Tests/SurgeTests/MatrixTests.swift +++ b/Tests/SurgeTests/MatrixTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2016 Wenbin Zhang, Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/PowerTests.swift b/Tests/SurgeTests/PowerTests.swift index aa91845..8f84707 100644 --- a/Tests/SurgeTests/PowerTests.swift +++ b/Tests/SurgeTests/PowerTests.swift @@ -1,5 +1,4 @@ -// Created by Wenbin Zhang on 2/13/16. -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/TrigonometricTests.swift b/Tests/SurgeTests/TrigonometricTests.swift index 1dd6b68..57f8531 100644 --- a/Tests/SurgeTests/TrigonometricTests.swift +++ b/Tests/SurgeTests/TrigonometricTests.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Tests/SurgeTests/XCTestCase+Surge.swift b/Tests/SurgeTests/XCTestCase+Surge.swift index dff987d..8dda562 100644 --- a/Tests/SurgeTests/XCTestCase+Surge.swift +++ b/Tests/SurgeTests/XCTestCase+Surge.swift @@ -1,4 +1,4 @@ -// Copyright © 2014–2015 Mattt Thompson (http://mattt.me) +// Copyright © 2014-2018 the Surge contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal