Example #1
0
File: Dsp.c Project: eriser/FxDSP
/*******************************************************************************
 Convolve */
Error_t
Convolve(float       *in1,
         unsigned    in1_length,
         float       *in2,
         unsigned    in2_length,
         float       *dest)
{
    
    unsigned resultLength = in1_length + (in2_length - 1);
#ifdef __APPLE__
    //Use Native vectorized convolution function if available
    float    *in2_end = in2 + (in2_length - 1);
    unsigned signalLength = (in2_length + resultLength);
    
    float padded[signalLength];
    
    //float zero = 0.0;
    ClearBuffer(padded, signalLength);
    
    // Pad the input signal with (filter_length - 1) zeros.
    cblas_scopy(in1_length, in1, 1, (padded + (in2_length - 1)), 1);
    vDSP_conv(padded, 1, in2_end, -1, dest, 1, resultLength, in2_length);
    
#else
    // Use (boring, slow) canonical implementation
    unsigned i;
    for (i = 0; i <resultLength; ++i)
    {
        unsigned kmin, kmax, k;
        dest[i] = 0;
        
        kmin = (i >= (in2_length - 1)) ? i - (in2_length - 1) : 0;
        kmax = (i < in1_length - 1) ? i : in1_length - 1;
        for (k = kmin; k <= kmax; k++)
        {
            dest[i] += in1[k] * in2[i - k];
        }
    }
    
    
#endif
    return NOERR;
}
Example #2
0
void CorrelationUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int channel) throw()
{
	const int blockSize = uGenOutput.getBlockSize();
	int numSamplesToProcess = blockSize;
	
	float* inputASamples = inputs[InputA].processBlock(shouldDelete, blockID, channel);
	float* inputBSamples = inputs[InputB].processBlock(shouldDelete, blockID, channel);
	float* outputSamples = uGenOutput.getSampleData();
	
    float* const windowsSamples = window.getDataUnchecked(0);
    float* const scoreSamples = score.getDataUnchecked(0);
	float* const bufferASamples = buffers.getDataUnchecked(InputBufferA);
	float* const bufferBSamples = buffers.getDataUnchecked(InputBufferB);
	float* const outputBufferSamples = buffers.getDataUnchecked(OutputBuffer);
	
	while(numSamplesToProcess > 0)
	{
		int bufferSamplesToProcess = length_ - bufferIndex;
	
		if(bufferSamplesToProcess > numSamplesToProcess)
		{			
			// buffer the inputs
			memcpy(bufferASamples + bufferIndex, inputASamples, numSamplesToProcess * sizeof(float));
			memcpy(bufferBSamples + bufferIndex, inputBSamples, numSamplesToProcess * sizeof(float));
			
            bufferIndex += numSamplesToProcess;
			inputASamples += numSamplesToProcess;
			inputBSamples += numSamplesToProcess;

			// ...and the output - output the lockedIndexOfMax into the outputSamples 
            outputIndex(outputSamples, numSamplesToProcess);
//            outputBuffer(outputSamples, numSamplesToProcess);
//            outputScore(outputSamples, numSamplesToProcess);
            
			outputSamples += numSamplesToProcess;
			numSamplesToProcess = 0;
		}
		else
		{
			numSamplesToProcess -= bufferSamplesToProcess;

			memcpy(bufferASamples + bufferIndex, inputASamples, bufferSamplesToProcess * sizeof(float));
			memcpy(bufferBSamples + bufferIndex, inputBSamples, bufferSamplesToProcess * sizeof(float));
			memset(outputBufferSamples, 0, (length_ + length_) * sizeof(float));
            
            //apply windows
            
            for (int i = 0; i < length_; i++)
            {
                bufferASamples[i] *= windowsSamples[i];
                bufferBSamples[i] *= windowsSamples[i];
            }
            
			bufferIndex += bufferSamplesToProcess;
			inputASamples += bufferSamplesToProcess;
			inputBSamples += bufferSamplesToProcess;
			
			vDSP_conv (bufferASamples, 1, 
                       bufferBSamples, 1,			
					   outputBufferSamples, 1, 
					   length_, length_);
                        
            for (int i = 0; i < length_; i++)
                scoreSamples[i] *= 0.9f;
            
            indexOfMax = findPeak(outputBufferSamples, length_);
            
            if ((indexOfMax >= 0) && (indexOfMax < length_))
            {
                if (lockedIndexOfMax >= 0)
                {
                    int diff = indexOfMax - lockedIndexOfMax;
                    
                    if (diff < 0)
                        diff = -diff;
                    
                    int maximum = length_ / 4;
                    diff = ugen::min(diff, maximum);
                    
                    int score = maximum - diff;
                    
                    float fScore = (float)score / maximum;
                    fScore = ugen::cubed(fScore);
                    
                    scoreSamples[indexOfMax] += fScore;
                }
                else
                {
                    scoreSamples[indexOfMax] += 1.f;
                }
            }
                        
            lockedIndexOfMax = findPeak(scoreSamples, length_);            
            
            // output the lockedIndexOfMax into the outputSamples 
            outputIndex(outputSamples, bufferSamplesToProcess);
//            outputBuffer(outputSamples, bufferSamplesToProcess);
//            outputScore(outputSamples, bufferSamplesToProcess);

            outputSamples += bufferSamplesToProcess;
			bufferSamplesToProcess = 0;
			bufferIndex = 0;
		}
	}
}