func minLen(size ...int) C.vDSP_Length { min := size[0] for i := 1; i < len(size); i++ { if size[i] < min { min = size[i] } } return C.vDSP_Length(min) }
func CreateFFTSetupD(log2n int, radix FFTRadix) (*FFTSetupD, error) { fftSetup := C.vDSP_create_fftsetupD(C.vDSP_Length(log2n), C.FFTRadix(radix)) if fftSetup == nil { return nil, ErrFailedToCreateFFTSetup } setup := &FFTSetupD{fftSetup} runtime.SetFinalizer(setup, destroyFFTSetupD) return setup, nil }
// Zidotpr calculates the conjugate dot product (or inner dot product) of complex vectors A and B and leave the result in complex vector C; single precision. func Zidotpr(input1 DSPSplitComplex, stride1 int, input2 DSPSplitComplex, stride2 int, result DSPSplitComplex) { var in1 C.DSPSplitComplex in1.realp = (*C.float)(&input1.Real[0]) in1.imagp = (*C.float)(&input1.Imag[0]) var in2 C.DSPSplitComplex in2.realp = (*C.float)(&input2.Real[0]) in2.imagp = (*C.float)(&input2.Imag[0]) var res C.DSPSplitComplex res.realp = (*C.float)(&result.Real[0]) res.imagp = (*C.float)(&result.Imag[0]) C.vDSP_zidotpr(&in1, C.vDSP_Stride(stride1), &in2, C.vDSP_Stride(stride2), &res, C.vDSP_Length(len(result.Real))) }
// Multiplies vector A by vector B and leaves the result in vector C; single precision. func Vmul(input1 []float32, stride1 int, input2 []float32, stride2 int, output []float32, outputStride int) { C.vDSP_vmul((*C.float)(&input1[0]), C.vDSP_Stride(stride1), (*C.float)(&input2[0]), C.vDSP_Stride(stride2), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride)) }
// Vector linear average; single precision. func Vavlin(input []float32, inputStride int, count float32, output []float32, outputStride int) { C.vDSP_vavlin((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.float)(&count), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride)) }
// BlkmanWindow creates a single-precision Blackman window. func BlkmanWindow(output []float32, flag WindowFlag) { C.vDSP_blkman_window((*C.float)(&output[0]), C.vDSP_Length(len(output)), C.int(flag)) }
// Meanv returns the mean of the input vector. func Meanv(input []float32, stride int) float32 { var mean C.float C.vDSP_meanv((*C.float)(&input[0]), C.vDSP_Stride(stride), &mean, C.vDSP_Length(len(input)/stride)) return float32(mean) }
// Vector negative values; single precision. func Vneg(input []float32, inputStride int, output []float32, outputStride int) { C.vDSP_vneg((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride)) }
// Zvphas calculates the complex vector phase. func Zvphas(input DSPSplitComplex, inputStride int, output []float32, outputStride int) { var srcC C.DSPSplitComplex srcC.realp = (*C.float)(&input.Real[0]) srcC.imagp = (*C.float)(&input.Imag[0]) C.vDSP_zvphas(&srcC, C.vDSP_Stride(inputStride), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output))) }
// Zrdesamp performs a complex-real downsample with anti-aliasing. func Zrdesamp(input DSPSplitComplex, decimationFactor int, coefficients []float32, output DSPSplitComplex) { var srcC C.DSPSplitComplex srcC.realp = (*C.float)(&input.Real[0]) srcC.imagp = (*C.float)(&input.Imag[0]) var dstC C.DSPSplitComplex dstC.realp = (*C.float)(&output.Real[0]) dstC.imagp = (*C.float)(&output.Imag[0]) C.vDSP_zrdesamp(&srcC, C.vDSP_Stride(decimationFactor), (*C.float)(&coefficients[0]), &dstC, C.vDSP_Length(len(output.Real)), C.vDSP_Length(len(coefficients))) }
// Desamp performs convolution with decimation. func Desamp(input []float32, desamplingFactor int, coeff []float32, output []float32) { C.vDSP_desamp((*C.float)(&input[0]), C.vDSP_Stride(desamplingFactor), (*C.float)(&coeff[0]), (*C.float)(&output[0]), C.vDSP_Length(len(output)), C.vDSP_Length(len(coeff))) }
// Ztoc_byte copies the contents of a split complex vector Z to an interleaved complex vector C; single precision. Operate on a byte buffer which contains complex64 func Ztoc_byte(input DSPSplitComplex, inputStride int, output []byte, outputStride int) { var splitComplex C.DSPSplitComplex splitComplex.realp = (*C.float)(&input.Real[0]) splitComplex.imagp = (*C.float)(&input.Imag[0]) C.vDSP_ztoc(&splitComplex, C.vDSP_Stride(inputStride), (*C.DSPComplex)(unsafe.Pointer(&output[0])), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/4/outputStride)) }
// Zop computes an out-of-place single-precision complex discrete Fourier transform of the // input vector, either from the time domain to the frequency domain (forward) or from the // frequency domain to the time domain (inverse). func (fs *FFTSetupD) Zop(input DSPDoubleSplitComplex, inputStride int, output DSPDoubleSplitComplex, outputStride int, log2n int, direction FFTDirection) { var inC C.DSPDoubleSplitComplex inC.realp = (*C.double)(&input.Real[0]) inC.imagp = (*C.double)(&input.Imag[0]) var outC C.DSPDoubleSplitComplex outC.realp = (*C.double)(&output.Real[0]) outC.imagp = (*C.double)(&output.Imag[0]) C.vDSP_fft_zopD(fs.cFFTSetupD, &inC, C.vDSP_Stride(inputStride), &outC, C.vDSP_Stride(outputStride), C.vDSP_Length(log2n), C.FFTDirection(direction)) }
// Zip computess an in-place single-precision complex discrete Fourier transform of the // input/output vector signal, either from the time domain to the frequency domain // (forward) or from the frequency domain to the time domain (inverse). func (fs *FFTSetupD) Zip(ioData DSPDoubleSplitComplex, stride, log2n int, direction FFTDirection) { var splitComplex C.DSPDoubleSplitComplex splitComplex.realp = (*C.double)(&ioData.Real[0]) splitComplex.imagp = (*C.double)(&ioData.Imag[0]) C.vDSP_fft_zipD(fs.cFFTSetupD, &splitComplex, C.vDSP_Stride(stride), C.vDSP_Length(log2n), C.FFTDirection(direction)) }
// Vector scalar add; single precision. func Vsadd(input []float32, inputStride int, add float32, output []float32, outputStride int) { C.vDSP_vsadd((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.float)(&add), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride)) }
// Vector scalar divide; single precision. func Vsdiv(input []float32, inputStride int, divisor float32, output []float32, outputStride int) { C.vDSP_vsdiv((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.float)(&divisor), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride)) }
// Vfix16_byte converts an array of single-precision floating-point values to signed 16-bit integer values, rounding towards zero. Output to a byte stream. func Vfix16_byte(input []float32, inputStride int, output []byte, outputStride int) { C.vDSP_vfix16((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.short)(unsafe.Pointer(&output[0])), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/2/outputStride)) }
// Vector sliding window sum; single precision. func Vswsum(input []float32, inputStride int, output []float32, outputStride, windowLen int) { C.vDSP_vswsum((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride), C.vDSP_Length(windowLen)) }
// Complex vector absolute values; double precision. func ZvabsD(input DSPDoubleSplitComplex, inputStride int, output []float64, outputStride int) { var in C.DSPDoubleSplitComplex in.realp = (*C.double)(&input.Real[0]) in.imagp = (*C.double)(&input.Imag[0]) C.vDSP_zvabsD(&in, C.vDSP_Stride(inputStride), (*C.double)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride)) }
// Vector convert power or amplitude to decibels; single precision. // α * log10(input(n)/zeroReference) [α is 20 if Amplitude (flag=1), or 10 if F is Power (flag=0)] func Vdbcon(input []float32, inputStride int, zeroReference float32, output []float32, outputStride int, flag DBFlag) { C.vDSP_vdbcon((*C.float)(&input[0]), C.vDSP_Stride(inputStride), (*C.float)(&zeroReference), (*C.float)(&output[0]), C.vDSP_Stride(outputStride), C.vDSP_Length(len(output)/outputStride), C.uint(flag)) }
// Vector minimum value; single precision. func Minv(input []float32, stride int) float32 { var out C.float C.vDSP_minv((*C.float)(&input[0]), C.vDSP_Stride(stride), &out, C.vDSP_Length(len(input)/stride)) return float32(out) }
// HammWindow creates a single-precision Hamming window. func HammWindow(output []float32, flag WindowFlag) { C.vDSP_hamm_window((*C.float)(&output[0]), C.vDSP_Length(len(output)), C.int(flag)) }
// Vector sum; single precision. func Sve(input []float32, inputStride int) float32 { var sum C.float C.vDSP_sve((*C.float)(&input[0]), C.vDSP_Stride(inputStride), &sum, C.vDSP_Length(len(input)/inputStride)) return float32(sum) }
// Ctoz copies the contents of an interleaved complex vector C to a split complex vector Z; single precision. func Ctoz(input []complex64, inputStride int, output DSPSplitComplex, outputStride int) { var splitComplex C.DSPSplitComplex splitComplex.realp = (*C.float)(&output.Real[0]) splitComplex.imagp = (*C.float)(&output.Imag[0]) n := 2 * len(output.Real) / outputStride if n2 := 2 * len(input) / inputStride; n2 < n { n = n2 } C.vDSP_ctoz((*C.DSPComplex)(unsafe.Pointer(&input[0])), C.vDSP_Stride(inputStride), &splitComplex, C.vDSP_Stride(outputStride), C.vDSP_Length(n)) }
// Zrip computess an in-place single-precision real discrete Fourier transform of the // input/output vector signal, either from the time domain to the frequency domain // (forward) or from the frequency domain to the time domain (inverse). func (fs *FFTSetup) Zrip(ioData DSPSplitComplex, stride, log2n int, direction FFTDirection) { var splitComplex C.DSPSplitComplex splitComplex.realp = (*C.float)(&ioData.Real[0]) splitComplex.imagp = (*C.float)(&ioData.Imag[0]) C.vDSP_fft_zrip(fs.cFFTSetup, &splitComplex, C.vDSP_Stride(stride), C.vDSP_Length(log2n), C.FFTDirection(direction)) }