转换参数以使 Swift 使用 vDSP API 进行编译

Posted

技术标签:

【中文标题】转换参数以使 Swift 使用 vDSP API 进行编译【英文标题】:Casting parameters to make Swift compile with vDSP API 【发布时间】:2014-06-09 02:47:05 【问题描述】:

我在尝试将 Accelerate 框架与 Swift 的 vDSP API 一起使用时遇到了一些问题。显然我做错了,尽管编译器给了我各种各样的警告

var srcAsFloat:CConstPointer<CFloat> = CFloat[](count: Int(width*height), repeatedValue: 0)
var dstAsFloat = CFloat[](count: Int(width*height), repeatedValue: 0)

if shouldClip 
    var min:CFloat = 0.0
    var max:CFloat = 255.0
    var l:vDSP_Stride = Int(width*height)
    vDSP_vclip(CConstPointer<CFloat>(&dstAsFloat), vDSP_Stride(1), CConstPointer<CFloat>(&min), CConstPointer<CFloat>(&max), CMutablePointer<CFloat>(&dstAsFloat), vDSP_Stride(1), l)

错误:

error: could not find an overload for 'init' that accepts the supplied arguments 
    vDSP_vclip(CConstPointer<CFloat>(&dstAsFloat), 
    vDSP_Stride(1), 
    CConstPointer<CFloat>(&min), 
    CConstPointer<CFloat>(&max), 
    CMutablePointer<CFloat>(&dstAsFloat), 
    vDSP_Stride(1), 
    l) – 

我试图摆脱它,但到目前为止,没有运气。

【问题讨论】:

你能发布你收到的警告/错误吗? 错误:找不到接受提供的参数的“init”的重载 vDSP_vclip(CConstPointer(&dstAsFloat), vDSP_Stride(1), CConstPointer(&min), CConstPointer(&max), CMutablePointer(&dstAsFloat), vDSP_Stride(1), l) 【参考方案1】:

好的,我想出了一个(可能不是最佳的)解决方案。我决定过渡到 Objective-C(并使用了稍微不同的函数)。

main.swift

import Foundation
func abs(x: matrix) -> matrix
    let N = x.count
    var arg1 = NSArray(array: x)

    var yy = abs_objc(arg1, CInt(N))

    var y = zeros(N)
    for i in 0..N
        y[i] = Double(yy[i])
    
    return y

abs_objc.m

#import <Accelerate/Accelerate.h>
double* abs_objc(NSArray * x, int N)
    // converting input to double *
    double * xx = (double *)malloc(sizeof(double) * N);
    for (int i=0; i<[x count]; i++) 
        xx[i] = [[x objectAtIndex:i] doubleValue];
    

    // init'ing output
    double * y = (double *)malloc(sizeof(double) * N);
    for (int i=0; i<N; i++)
        y[i] = 0;
    

    vDSP_vabsD(xx,1,y,1,N);

    return y;

swix-Bridging-Header.h

#import <Foundation/Foundation.h>
double* abs_objc(NSArray * x, int N);

【讨论】:

【参考方案2】:

我一直在使用 vDSP 来创建通用矩阵语言。

我发现这种方法最容易获得正确的指针类型。

希望你觉得它有用(这可能也不是最佳的,但只是一个开始)。

import Accelerate
func myFunction(width:Float, height:Float) 

    var dstAsFloat = CFloat[](count: Int(width*height), repeatedValue: 0)
    var min:CFloat = 0.0
    var max:CFloat = 255.0

    func vclipPointerConversion(dstAsFloat:CMutablePointer<CFloat>) 
        vDSP_vclip(CConstPointer<CFloat>(nil,dstAsFloat.value), vDSP_Stride(1),
            &min, &max, dstAsFloat, vDSP_Stride(1), CUnsignedLong(width*height))
    

    vclipPointerConversion(&dstAsFloat)

    //...
    // return whatever you wanted

【讨论】:

【参考方案3】:

我通过一些调整让它工作。请注意,第一个参数没有 & 符号 (CConstPointer)。但是第二个确实(我对 src 和 dst 使用相同的指针)。我还替换了值的强制转换(必要的)。您需要将 CFloats 用于上限值。代码如下:

let width: UInt = CGBitmapContextGetWidth(context)
let height: UInt = CGBitmapContextGetHeight(context)

var dstAsFloat = CFloat[](count: Int(width*height), repeatedValue: 0)

if shouldClip 
    var min:CFloat = 0.0
    var max:CFloat = 255.0
    vDSP_vclip(dstAsFloat, CLong(1), &min, &max, &dstAsFloat, CLong(1), UInt(width*height))


【讨论】:

以上是关于转换参数以使 Swift 使用 vDSP API 进行编译的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 vDSP / Accelerate in swift for iOS 计算向量元素的平方根

vDSP_desamp FIR 滤波器采样历史连续性

如何在 iOS 中使用 vDSP 将声音文件转换为 FFT

Apple 的 Accelerate vDSP:如何从 FFT 中获取复数向量的参数

在 Swift 中将数组转换为 Alamofire 参数

使用 vDSP 的 iPhone4s、iPhone 5 每秒最大 FFT 数