Created
April 9, 2013 19:38
-
-
Save praeclarum/5348699 to your computer and use it in GitHub Desktop.
DSP functions for Xamarin.iOS bound to the Accelerate framework. See it in action by buying my Spectrogram app for iOS: https://itunes.apple.com/us/app/live-spectrogram/id630831185
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
namespace Circuit | |
{ | |
public static class Dsp | |
{ | |
class FftSetupD : IDisposable | |
{ | |
public IntPtr Handle; | |
public FftSetupD (int nlog2) | |
{ | |
Handle = vDSP_create_fftsetupD (nlog2, FftRadix.Radix2); | |
} | |
~FftSetupD () | |
{ | |
DisposeIt (); | |
} | |
public void Dispose () | |
{ | |
GC.SuppressFinalize (this); | |
DisposeIt (); | |
} | |
void DisposeIt () | |
{ | |
vDSP_destroy_fftsetupD (Handle); | |
Handle = IntPtr.Zero; | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_create_fftsetupD")] | |
unsafe static extern IntPtr vDSP_create_fftsetupD (int log2n, FftRadix radix); | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_destroy_fftsetupD")] | |
unsafe static extern void vDSP_destroy_fftsetupD (IntPtr setup); | |
} | |
class FftSetup : IDisposable | |
{ | |
public IntPtr Handle; | |
public FftSetup (int nlog2) | |
{ | |
Handle = vDSP_create_fftsetup (nlog2, FftRadix.Radix2); | |
} | |
~FftSetup () | |
{ | |
DisposeIt (); | |
} | |
public void Dispose () | |
{ | |
GC.SuppressFinalize (this); | |
DisposeIt (); | |
} | |
void DisposeIt () | |
{ | |
vDSP_destroy_fftsetup (Handle); | |
Handle = IntPtr.Zero; | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_create_fftsetup")] | |
unsafe static extern IntPtr vDSP_create_fftsetup (int log2n, FftRadix radix); | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_destroy_fftsetup")] | |
unsafe static extern void vDSP_destroy_fftsetup (IntPtr setup); | |
} | |
enum FftDirection : int | |
{ | |
Forward = 1, | |
Inverse = -1, | |
} | |
enum FftRadix : int | |
{ | |
Radix2 = 0, | |
} | |
[StructLayout (LayoutKind.Sequential)] | |
unsafe struct SplitComplexD | |
{ | |
public double* Realp; | |
public double* Imagp; | |
} | |
[StructLayout (LayoutKind.Sequential)] | |
unsafe struct SplitComplex | |
{ | |
public float* Realp; | |
public float* Imagp; | |
} | |
public static IDisposable SetupFftD (int nlog2) | |
{ | |
return new FftSetupD (nlog2); | |
} | |
public static IDisposable SetupFft (int nlog2) | |
{ | |
return new FftSetup (nlog2); | |
} | |
public static void Fft (ComplexDataD data, object setup, bool forward) | |
{ | |
unsafe { | |
fixed (double *realp = data.Reals) { | |
fixed (double *imagp = data.Imags) { | |
SplitComplexD d; | |
d.Realp = realp; | |
d.Imagp = imagp; | |
vDSP_fft_zipD (((FftSetupD)setup).Handle, ref d, 1, GetNLog2 (data.Length), forward ? FftDirection.Forward : FftDirection.Inverse); | |
} | |
} | |
} | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_fft_zipD")] | |
unsafe static extern void vDSP_fft_zipD (IntPtr setup, ref SplitComplexD ioData, int stride, int log2n, FftDirection direction); | |
public static void Fft (ComplexData data, object setup, bool forward) | |
{ | |
unsafe { | |
fixed (float *realp = data.Reals) { | |
fixed (float *imagp = data.Imags) { | |
SplitComplex d; | |
d.Realp = realp; | |
d.Imagp = imagp; | |
vDSP_fft_zip (((FftSetup)setup).Handle, ref d, 1, GetNLog2 (data.Length), forward ? FftDirection.Forward : FftDirection.Inverse); | |
} | |
} | |
} | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_fft_zip")] | |
unsafe static extern void vDSP_fft_zip (IntPtr setup, ref SplitComplex ioData, int stride, int log2n, FftDirection direction); | |
public static void GetMagnitudesSquared (ComplexDataD data, double[] output) | |
{ | |
unsafe { | |
fixed (double *realp = data.Reals) { | |
fixed (double *imagp = data.Imags) { | |
SplitComplexD d; | |
d.Realp = realp; | |
d.Imagp = imagp; | |
vDSP_zvmagsD (ref d, 1, output, 1, output.Length); | |
} | |
} | |
} | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_zvmagsD")] | |
unsafe static extern void vDSP_zvmagsD (ref SplitComplexD a, int stride, double[] c, int k, int n); | |
public static void GetMagnitudesSquared (ComplexData data, float[] output) | |
{ | |
unsafe { | |
fixed (float *realp = data.Reals) { | |
fixed (float *imagp = data.Imags) { | |
SplitComplex d; | |
d.Realp = realp; | |
d.Imagp = imagp; | |
vDSP_zvmags (ref d, 1, output, 1, output.Length); | |
} | |
} | |
} | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_zvmags")] | |
unsafe static extern void vDSP_zvmags (ref SplitComplex a, int stride, float[] c, int k, int n); | |
public static void GetDecibelsFromPower (double[] power, double[] reference, double[] output) | |
{ | |
vDSP_vdbconD (power, 1, reference, output, 1, output.Length, 0); | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_vdbconD")] | |
unsafe static extern void vDSP_vdbconD (double[] a, int i, double[] b, double[] c, int k, int n, uint f); | |
public static void GetDecibelsFromPower (float[] power, float[] reference, float[] output) | |
{ | |
vDSP_vdbcon (power, 1, reference, output, 1, output.Length, 0); | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_vdbcon")] | |
unsafe static extern void vDSP_vdbcon (float[] a, int i, float[] b, float[] c, int k, int n, uint f); | |
public static void Lint (float[] a, float[] b, float[] output) | |
{ | |
vDSP_vlint (a, b, 1, output, 1, output.Length, a.Length); | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_vlint")] | |
unsafe static extern void vDSP_vlint (float[] a, float[] b, int j, float[] c, int k, int n, int m); | |
public static void MultiplyAndAdd (float[] a, float b, float c, float[] output) | |
{ | |
vDSP_vsmsa (a, 1, ref b, ref c, output, 1, output.Length); | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal", EntryPoint = "vDSP_vsmsa")] | |
unsafe static extern void vDSP_vsmsa (float[] a, int i, ref float b, ref float c, float[] d, int l, int n); | |
public static void Clip (float[] a, float b, float c, float[] output) | |
{ | |
vDSP_vclip (a, 1, ref b, ref c, output, 1, output.Length); | |
} | |
[System.Runtime.InteropServices.DllImport ("__Internal")] | |
unsafe static extern void vDSP_vclip (float[] a, int i, ref float b, ref float c, float[] d, int l, int n); | |
} | |
public class ComplexDataD | |
{ | |
public readonly double[] Reals; | |
public readonly double[] Imags; | |
public int Length { get { return Reals.Length; } } | |
public ComplexDataD (int n) | |
{ | |
Reals = new double[n]; | |
Imags = new double[n]; | |
} | |
} | |
public class ComplexData | |
{ | |
public readonly float[] Reals; | |
public readonly float[] Imags; | |
public int Length { get { return Reals.Length; } } | |
public ComplexData (int n) | |
{ | |
Reals = new float[n]; | |
Imags = new float[n]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment