float FourthOrderFilter::process(float sample){
    float Aout, Bout;
    vDSP_vmul(A, 1, za1, 1, temp, 1, 4);
    vDSP_sve(temp, 1, &Aout, 4);
    vDSP_vmul(B, 1, zb1, 1, temp, 1, 4);
    vDSP_sve(temp, 1, &Bout, 4);
    float output = b0*sample + Bout - Aout;
    
    za1--;
    zb1--;
    
    if (za1 < Za) { // if we have reached the beginning of the buffer
    
        // copy za2, za3, za4, zb2, zb3, zb4 back to the end of the array
        *ZaEnd       = *(Za + 2);
        *(ZaEnd - 1) = *(Za + 1);
        *(ZaEnd - 2) = *Za;
        *ZbEnd       = *(Za + 2);
        *(ZbEnd - 1) = *(Zb + 1);
        *(ZbEnd - 2) = *Zb;
        
        // reset pointers
        za1 = ZaEnd - 3;
        zb1 = ZbEnd - 3;
    }
    
    *za1 = output;
    *zb1 = sample;
    
    return output;
}
Beispiel #2
0
void scfft_dowindowing(float *data, unsigned int winsize, unsigned int fullsize, unsigned short log2_winsize, short wintype, float scalefac){
	int i;
	if(wintype != WINDOW_RECT){
		float *win = fftWindow[wintype][log2_winsize];
		if (!win) return;
		#if SC_DARWIN
			vDSP_vmul(data, 1, win, 1, data, 1, winsize);
		#else
			--win;
			float *in = data - 1;
			for (i=0; i< winsize ; ++i) {
				*++in *= *++win;
			}
		#endif

	}

		// scale factor is different for different libs. But the compiler switch here is about using vDSP's fast multiplication method.
	#if SC_DARWIN
		vDSP_vsmul(data, 1, &scalefac, data, 1, winsize);
	#else
		for(int i=0; i<winsize; ++i){
			data[i] *= scalefac;
		}
	#endif

	// Zero-padding:
	memset(data + winsize, 0, (fullsize - winsize) * sizeof(float));
}
Beispiel #3
0
void FFTAccelerate::doFFTReal(float samples[], float amp[], int numSamples)
{
	int i;
	vDSP_Length log2n = log2f(numSamples);
    int nOver2 = numSamples/2;
    //-- window
    //vDSP_blkman_window(window, windowSize, 0);
    vDSP_vmul(samples, 1, window, 1, in_real, 1, numSamples);

    //Convert float array of reals samples to COMPLEX_SPLIT array A
	vDSP_ctoz((COMPLEX*)in_real,2,&A,1,nOver2);

    //Perform FFT using fftSetup and A
    //Results are returned in A
	vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);
    
    // scale by 1/2*n because vDSP_fft_zrip doesn't use the right scaling factors natively ("for better performances")
    {
        const float scale = 1.0f/(2.0f*(float)numSamples);
        vDSP_vsmul( A.realp, 1, &scale, A.realp, 1, numSamples/2 );
        vDSP_vsmul( A.imagp, 1, &scale, A.imagp, 1, numSamples/2 );
    }
    
    //Convert COMPLEX_SPLIT A result to float array to be returned
    /*amp[0] = A.realp[0]/(numSamples*2);
	for(i=1;i<numSamples/2;i++)
		amp[i]=sqrt(A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i]);*/
    
    // collapse split complex array into a real array.
    // split[0] contains the DC, and the values we're interested in are split[1] to split[len/2] (since the rest are complex conjugates)
    vDSP_zvabs( &A, 1, amp, 1, numSamples/2 );
}
Beispiel #4
0
// windowSize and windowInterval are constrained to be multiples of the block size
void DspEnvelope::processDspWithIndex(int fromIndex, int toIndex) {
  // copy the input into the signal buffer
  memcpy(signalBuffer + numSamplesReceived, dspBufferAtInlet0, numBytesInBlock);
  numSamplesReceived += blockSizeInt;
  numSamplesReceivedSinceLastInterval += blockSizeInt;
  if (numSamplesReceived >= windowSize) {
    numSamplesReceived = 0;
  }
  if (numSamplesReceivedSinceLastInterval == windowInterval) {
    numSamplesReceivedSinceLastInterval -= windowInterval;
    // apply hanning window to signal and calculate Root Mean Square
    float rms = 0.0f;
    if (ArrayArithmetic::hasAccelerate) {
      #if __APPLE__
      vDSP_vsq(signalBuffer, 1, rmsBuffer, 1, windowSize); // signalBuffer^2 
      vDSP_vmul(rmsBuffer, 1, hanningCoefficients, 1, rmsBuffer, 1, windowSize); // * hanning window
      vDSP_sve(rmsBuffer, 1, &rms, windowSize); // sum the result
      #endif
    } else {
      for (int i = 0; i < windowSize; i++) {
        rms += signalBuffer[i] * signalBuffer[i] * hanningCoefficients[i];
      }
    }
    // finish RMS calculation. sqrt is removed as it can be combined with the log operation.
    // result is normalised such that 1 RMS == 100 dB
    rms = 10.0f * log10f(rms) + 100.0f;

    PdMessage *outgoingMessage = getNextOutgoingMessage(0);
    // graph will schedule this at the beginning of the next block because the timestamp will be
    // behind the block start timestamp
    outgoingMessage->setTimestamp(0.0);
    outgoingMessage->setFloat(0, (rms < 0.0f) ? 0.0f : rms);
    graph->scheduleMessage(this, 0, outgoingMessage);
  }
}
Beispiel #5
0
/*******************************************************************************
 VectorVectorMultiply */
Error_t
VectorVectorMultiply(float          *dest,
                     const float    *in1,
                     const float    *in2,
                     unsigned       length)
{
#ifdef __APPLE__
    // Use the Accelerate framework if we have it
    vDSP_vmul(in1, 1, in2, 1, dest, 1, length);
    
#else
    // Otherwise do it manually
    unsigned i;
    const unsigned end = 4 * (length / 4);
    for (i = 0; i < end; i+=4)
    {
        dest[i] = in1[i] * in2[i];
        dest[i + 1] = in1[i + 1] * in2[i + 1];
        dest[i + 2] = in1[i + 2] * in2[i + 2];
        dest[i + 3] = in1[i + 3] * in2[i + 3];
    }
    for (i = end; i < length; ++i)
    {
        dest[i] = in1[i] * in2[i];
    }
    
#endif
    return NOERR;
}
Beispiel #6
0
/* Calculate the power spectrum */
void fft::powerSpectrum_vdsp(int start, float *data, float *window, float *magnitude,float *phase) {
	
    uint32_t        i;
	
	//multiply by window
	vDSP_vmul(data, 1, window, 1, in_real, 1, n);

	//convert to split complex format - evens and odds
	vDSP_ctoz((COMPLEX *) in_real, 2, &A, 1, half);
	
	
	//calc fft
	vDSP_fft_zrip(setupReal, &A, 1, log2n, FFT_FORWARD);
	
	//scale by 2 (see vDSP docs)
	static float scale=0.5 ;
	vDSP_vsmul(A.realp, 1, &scale, A.realp, 1, half);
	vDSP_vsmul(A.imagp, 1, &scale, A.imagp, 1, half);

	//back to split complex format
	vDSP_ztoc(&A, 1, (COMPLEX*) out_real, 2, half);
	
	//convert to polar
	vDSP_polar(out_real, 2, polar, 2, half);
	
	for (i = 0; i < half; i++) {
		magnitude[i]=polar[2*i]+1.0;
		phase[i]=polar[2*i + 1];
	}
	
	
	
}
void vmul(const float* source1P, int sourceStride1, const float* source2P, int sourceStride2, float* destP, int destStride, size_t framesToProcess)
{
#if CPU(X86)
    ::vmul(source1P, sourceStride1, source2P, sourceStride2, destP, destStride, framesToProcess);
#else
    vDSP_vmul(source1P, sourceStride1, source2P, sourceStride2, destP, destStride, framesToProcess);
#endif
}
void BinaryMultiplyUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int channel) throw() 
{ 
	const int numSamplesToProcess = uGenOutput.getBlockSize(); 
	float* const outputSamples = uGenOutput.getSampleData(); 
	const float* const leftOperandSamples = inputs[LeftOperand].processBlock(shouldDelete, blockID, channel); 
	const float* const rightOperandSamples = inputs[RightOperand].processBlock(shouldDelete, blockID, channel); 
	vDSP_vmul(leftOperandSamples, 1, rightOperandSamples, 1, outputSamples, 1, numSamplesToProcess);
}
Beispiel #9
0
void vmul(const float* source1P, int sourceStride1, const float* source2P, int sourceStride2, float* destP, int destStride, size_t framesToProcess)
{
#if defined(__ppc__) || defined(__i386__)
    ::vmul(source1P, sourceStride1, source2P, sourceStride2, destP, destStride, framesToProcess);
#else
    vDSP_vmul(source1P, sourceStride1, source2P, sourceStride2, destP, destStride, framesToProcess);
#endif
}
static void PerformFFT(float * input, float * window, COMPLEX_SPLIT &fftData, FFTSetup &setup, size_t N)
{	
	// windowing
	vDSP_vmul(input, 1, window, 1, input, 1, N);
	
	// FFT
	vDSP_ctoz((COMPLEX *) input, 2, &fftData, 1, N/2);
	vDSP_fft_zrip(setup, &fftData, 1, (size_t)ceilf(log2f(N)), kFFTDirection_Forward);
	
	// zero-ing out Nyquist freq
	fftData.imagp[0] = 0.0f;
}
Beispiel #11
0
t_int *errfilt_perf_coeff(t_int *w)
{
	t_float *in = (t_float *)(w[1]);
	t_float *coeffIn = (t_float *)(w[2]);
	t_float *coeffIdxIn = (t_float *)(w[3]);
	t_errfilt *x = (t_errfilt *)(w[4]);
	t_float *out = (t_float *)(w[5]);
	int n = (int)(w[6]);
	int order = x->a_order;
	int i, in_idx = 0, out_idx = 0;
	t_float val = 0.0;
	float sum = 0.0;
	
	while(n--) {
		//get rid of NANs
		if(IS_NAN_FLOAT(coeffIn[in_idx])) coeffIn[in_idx] = 0.0;
		in_idx++;
	}
	
	in_idx = 0;
	n = (int)(w[6]);
	
	//look at coefficient index, if not zeros, buffer in coefficients
	while (n--) {
		if ((int)(coeffIdxIn[in_idx]) > 0) {
			x->a_bBuff[(int)(coeffIdxIn[in_idx])-1] = coeffIn[in_idx];
			if ((int)(coeffIdxIn[in_idx]) == order) {
				for(i = 0; i < order; i++) {
					x->a_b[i] = x->a_bBuff[i];
				}
			}
		}
		in_idx++;
	}
	
	n = (int)(w[6]);
	
	while (n--) { 
		val = in[out_idx];
		vDSP_vmul(x->a_b,1,x->a_x,1,x->a_tempVec,1,order);
		vDSP_sve(x->a_tempVec,1,&sum,order);
		val -= sum;
		//for (i=0; i < order; i++) val -= x->a_b[i] * x->a_x[i];
		for (i=order-1; i>0; i--) x->a_x[i] = x->a_x[i-1];
		x->a_x[0] = in[out_idx];		
			
		out[out_idx] = (float)val;
		out_idx++;
	}
	
	return (w+7);
}
Beispiel #12
0
Pitch PitchDetector::process(float *input, unsigned int numberOfSamples)
{
    assert(this->numberOfSamples==numberOfSamples);
    int n = numberOfSamples;
    float *originalReal = this->FFTBuffer;
    
    // 1.1.时域上加窗
    vDSP_vmul(input, 1, this->windowFunc, 1, originalReal, 1, n);
    // 分前后加窗没什么不一样啊
//    vDSP_vmul(input, 1, this->windowFunc, 1, originalReal+(n/2), 1, n/2);
//    vDSP_vmul(input+(n/2), 1, this->windowFunc+(n/2), 1, originalReal, 1, n/2);
    
    // 2.拆成复数形似{1+2i, 3+4i, ..., 1023+1024i} 原始数组可以认为是(COMPLEX*)交错存储 现在拆成COMPLEX_SPLIT非交错(分轨式)存储
    vDSP_ctoz((COMPLEX*)originalReal, 2, &this->A, 1, n/2); // 读取originalReal以2的步长塞进A里面
    
//    // 3.fft变换的预设
    float originalRealInLog2 = log2f(n);
//    FFTSetup setupReal = vDSP_create_fftsetup(originalRealInLog2, FFT_RADIX2);
    
    // 4.傅里叶变换
    vDSP_fft_zrip(this->setupReal, &this->A, 1, originalRealInLog2, FFT_FORWARD);
    
    // 5.转换成能量值
    vDSP_zvabs(&this->A, 1, this->magnitudes, 1, n/2);
    Float32 one = 1;
    vDSP_vdbcon(this->magnitudes, 1, &one, this->magnitudes, 1, n/2, 0);
    
    // 6.获取基频f0
    float maxValue;
    vDSP_Length index;
    vDSP_maxvi(this->magnitudes, 1, &maxValue, &index, n/2);
    // 6.1.微调参数
    double alpha    = this->magnitudes[index - 1];
    double beta     = this->magnitudes[index];
    double gamma    = this->magnitudes[index + 1];
    double p = 0.5 * (alpha - gamma) / (alpha - 2 * beta + gamma);
    
    // 7.转换为频率 indexHZ = index * (SampleRate / (n/2))
    float indexHZ = (index+p) * ((this->sampleRate*1.0) / n);
    
    // 8.乐理信息生成
    Pitch pitch;
    pitch.frequency = indexHZ;
    pitch.amplitude = beta;
    pitch.key = 12 * log2(indexHZ / 127.09) + 28.5;
    pitch.octave = (pitch.key - 3.0) / 12 + 1;
    calStep(&pitch);
    pitch.stepString = calStep(indexHZ);
    
    return pitch;
}
Beispiel #13
0
void ifft(FFT_FRAME* frame, float* outputBuffer)
{
    // get pointer to fft object
    FFT* fft = frame->fft;

    // perform in-place fft inverse
    vDSP_fft_zrip(fft->fftSetup, &frame->buffer, 1, fft->logTwo, FFT_INVERSE);
    
    // The output signal is now in a split real form.  Use the  function vDSP_ztoc to get a split real vector. 
    vDSP_ztoc(&frame->buffer, 1, (COMPLEX *)outputBuffer, 2, fft->sizeOverTwo);
    
    // This applies the windowing
    if (fft->window != NULL)
    	vDSP_vmul(outputBuffer, 1, fft->window, 1, outputBuffer, 1, fft->size);
}
Beispiel #14
0
void fft(FFT_FRAME* frame, float* audioBuffer)
{
	FFT* fft = frame->fft;
    
    // Do some data packing stuff
    vDSP_ctoz((COMPLEX*)audioBuffer, 2, &frame->buffer, 1, fft->sizeOverTwo);
    
    // This applies the windowing
    if (fft->window != NULL)
    	vDSP_vmul(audioBuffer, 1, fft->window, 1, audioBuffer, 1, fft->size);
    
    // Actually perform the fft
    vDSP_fft_zrip(fft->fftSetup, &frame->buffer, 1, fft->logTwo, FFT_FORWARD);
    
    // Do some scaling
    vDSP_vsmul(frame->buffer.realp, 1, &fft->normalize, frame->buffer.realp, 1, fft->sizeOverTwo);
    vDSP_vsmul(frame->buffer.imagp, 1, &fft->normalize, frame->buffer.imagp, 1, fft->sizeOverTwo);
    
    // Zero out DC offset
    frame->buffer.imagp[0] = 0.0;
}
Beispiel #15
0
void FFTAccelerate::doFFTReal(float samples[], float amp[], int numSamples)
{
	int i;
	vDSP_Length log2n = log2f(numSamples);
    int nOver2 = numSamples/2;
    //-- window
    //vDSP_blkman_window(window, windowSize, 0);
    vDSP_vmul(samples, 1, window, 1, in_real, 1, numSamples);

    //Convert float array of reals samples to COMPLEX_SPLIT array A
	vDSP_ctoz((COMPLEX*)in_real,2,&A,1,nOver2);

    //Perform FFT using fftSetup and A
    //Results are returned in A
	vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);
    
    //Convert COMPLEX_SPLIT A result to float array to be returned
    amp[0] = A.realp[0]/(numSamples*2);
	for(i=1;i<numSamples/2;i++)
		amp[i]=sqrt(A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i]);
}
Beispiel #16
0
void fftIp(FFT* fftObject, float* audioBuffer)
{
    // Creating pointer of COMPLEX_SPLIT to use in calculations (points to same data as audioBuffer)
    COMPLEX_SPLIT* fftBuffer = (COMPLEX_SPLIT *)&audioBuffer[0];
    
    // Apply windowing
    if (fftObject->window != NULL)
        vDSP_vmul(audioBuffer, 1, fftObject->window, 1, audioBuffer, 1, fftObject->size);
    
    // This seems correct-ish TODO: check casting
    vDSP_ctoz((COMPLEX*)audioBuffer, 2, fftBuffer, 1, fftObject->sizeOverTwo);
    
    // Perform fft
    vDSP_fft_zrip(fftObject->fftSetup, fftBuffer, 1, fftObject->logTwo, FFT_FORWARD);
    
    // Do scaling
    vDSP_vsmul(fftBuffer->realp, 1, &fftObject->normalize, fftBuffer->realp, 1, fftObject->sizeOverTwo);
    vDSP_vsmul(fftBuffer->imagp, 1, &fftObject->normalize, fftBuffer->imagp, 1, fftObject->sizeOverTwo);
    
    // zero out DC offset
    fftBuffer->imagp[0] = 0.0;
}
Beispiel #17
0
void fft::inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase) {
	uint32_t i;
	
	for (i = 0; i < half; i++) {
//		polar[2*i] = pow(10.0, magnitude[i] / 20.0) - 1.0;
		polar[2*i] = magnitude[i] - 1.0;
		polar[2*i + 1] = phase[i];
	}	
	
	vDSP_rect(polar, 2, in_real, 2, half);
	
	vDSP_ctoz((COMPLEX*) in_real, 2, &A, 1, half);
	vDSP_fft_zrip(setupReal, &A, 1, log2n, FFT_INVERSE);
	vDSP_ztoc(&A, 1, (COMPLEX*) out_real, 2, half);
	
	static float scale = 1./n;
	vDSP_vsmul(out_real, 1, &scale, out_real, 1, n);

	//multiply by window
	vDSP_vmul(out_real, 1, window, 1, finalOut, 1, n);
	
}
Beispiel #18
0
void mul( const float *arrayA, const float *arrayB, float *result, size_t length )
{
	vDSP_vmul( arrayA, 1, arrayB, 1, result, 1, length );
}
Beispiel #19
0
// ---------------------------------------------
// vector math
//
void siglab_sbMpy3(float *src1, float *src2, float *dst, int nel)
{
  vDSP_vmul(src1, 1, src2, 1, dst, 1, nel);
}
inline void maxiCollider::createGabor(flArr &atom, const float freq, const float sampleRate, const uint length, 
						 float startPhase, const float kurtotis, const float amp) {
	atom.resize(length);
    flArr sine;
    sine.resize(length);
    
//	float gausDivisor = (-2.0 * kurtotis * kurtotis);
//    float phase =-1.0;
    
    double *env = maxiCollider::envCache.getWindow(length);
#ifdef __APPLE_CC__	    
    vDSP_vdpsp(env, 1, &atom[0], 1, length);
#else    
	for(uint i=0; i < length; i++) {
        atom[i] = env[i];
    }
#endif
    
//#ifdef __APPLE_CC__	    
//    vDSP_vramp(&phase, &inc, &atom[0], 1, length);
//    vDSP_vsq(&atom[0], 1,  &atom[0], 1, length);
//    vDSP_vsdiv(&atom[0], 1, &gausDivisor, &atom[0], 1, length);
//    for(uint i=0; i < length; i++) atom[i] = exp(atom[i]);
//#else
//	for(uint i=0; i < length; i++) {
//		//gaussian envelope
//		atom[i] = exp((phase* phase) / gausDivisor);
//        phase += inc;
//    }
//#endif
    
	float cycleLen = sampleRate / freq;
	float maxPhase = length / cycleLen;
	float inc = 1.0 / length;

	
#ifdef __APPLE_CC__	
    flArr interpConstants;
    interpConstants.resize(length);
    float phase = 0.0;
    vDSP_vramp(&phase, &inc, &interpConstants[0], 1, length);
    vDSP_vsmsa(&interpConstants[0], 1, &maxPhase, &startPhase, &interpConstants[0], 1, length);
    float waveTableLength = 512;
    vDSP_vsmul(&interpConstants[0], 1, &waveTableLength, &interpConstants[0], 1, length);
    for(uint i=0; i < length; i++) {
        interpConstants[i] = fmod(interpConstants[i], 512.0f); 
    }
    vDSP_vlint(sineBuffer2, &interpConstants[0], 1, &sine[0], 1, length, 514);
    vDSP_vmul(&atom[0], 1, &sine[0], 1, &atom[0], 1,  length);
	vDSP_vsmul(&atom[0], 1, &amp, &atom[0], 1, length);
#else
	maxPhase *= TWOPI;
    for(uint i=0; i < length; i++) {
		//multiply by sinewave
		float x = inc * i;
		sine[i] = sin((x * maxPhase) + startPhase);
	}
	for(uint i=0; i < length; i++) {
        atom[i] *= sine[i];
		atom[i] *= amp;
	}
#endif
}