Ejemplo n.º 1
0
void AudioProcAnalyzePitch(int16_t * samples,
                           uint8_t gain,
                           int16_t ** raw_buckets,
                           int16_t ** full_buckets,
                           int16_t ** octave_buckets) {
  // Apply a window.
  VectorWindow(ANALOG_BUFFER_LEN, samples, samples, window);

  // Apply gain and convert to complex.
  for (unsigned i = 0; i < ANALOG_BUFFER_LEN; ++i) {
    complex_buf[i].real = samples[i] * gain;
    complex_buf[i].imag = 0;
  }

  // In-place FFT.
  FFTComplexIP(ANALOG_LOG2_BUFFER_LEN, complex_buf, twiddle, COEFFS_IN_DATA);
  BitReverseComplex(ANALOG_LOG2_BUFFER_LEN, complex_buf);

  // Compute magnitude (first half of the buffer).
  SquareMagnitudeCplx(ANALOG_BUFFER_LEN / 2, complex_buf, samples);

  // Harmonic suppression.
  for (int i = ANALOG_BUFFER_LEN / 2 - 1; i >= 0; --i) {
    samples[i] -= samples[i / 2] / 2;
    if (samples[i] < 0) samples[i] = 0;
  }

  // Apply bucketing.
  *raw_buckets = samples + ANALOG_BUFFER_LEN / 2;
  *full_buckets = *raw_buckets + PITCH_COUNT;
  *octave_buckets = *full_buckets + BUCKET_COUNT;
  Bucket(samples, *raw_buckets, *full_buckets, *octave_buckets);
}
Ejemplo n.º 2
0
int main(void)
{
	int i = 0;
	fractional *p_real = &sigCmpx[0].real ;
	fractcomplex *p_cmpx = &sigCmpx[0] ;


#ifndef FFTTWIDCOEFFS_IN_PROGMEM					/* Generate TwiddleFactor Coefficients */
	TwidFactorInit (LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0);	/* We need to do this only once at start-up */
#endif

	for ( i = 0; i < FFT_BLOCK_LENGTH; i++ )/* The FFT function requires input data */
	{					/* to be in the fractional fixed-point range [-0.5, +0.5]*/
		*p_real = *p_real >>1 ;		/* So, we shift all data samples by 1 bit to the right. */
		*p_real++;			/* Should you desire to optimize this process, perform */
	}					/* data scaling when first obtaining the time samples */
						/* Or within the BitReverseComplex function source code */

	p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real ;	/* Set up pointers to convert real array */
	p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1] ; /* to a complex array. The input array initially has all */
						/* the real input samples followed by a series of zeros */


	for ( i = FFT_BLOCK_LENGTH; i > 0; i-- ) /* Convert the Real input sample array */
	{					/* to a Complex input sample array  */
		(*p_cmpx).real = (*p_real--);	/* We will simpy zero out the imaginary  */
		(*p_cmpx--).imag = 0x0000;	/* part of each data sample */
	}

	/* Perform FFT operation */
#ifndef FFTTWIDCOEFFS_IN_PROGMEM
	FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA);
#else
	FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));
#endif

	/* Store output samples in bit-reversed order of their addresses */
	BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]);

	/* Compute the square magnitude of the complex FFT output array so we have a Real output vetor */
	SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);

	/* Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy*/
	/* i.e., the largest spectral component */
	VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);

	/* Compute the frequency (in Hz) of the largest spectral component */
	peakFrequency = peakFrequencyBin*(SAMPLING_RATE/FFT_BLOCK_LENGTH);

        while (1);	/* Place a breakpoint here and observe the watch window variables */
}
Ejemplo n.º 3
0
int main(void) {
    ex_sask_init();

    /*Initialise Audio input and output function*/
    ADCChannelInit(pADCChannelHandle, adcBuffer);
    OCPWMInit(pOCPWMHandle, ocPWMBuffer);

    /*Start Audio input and output function*/
    ADCChannelStart(pADCChannelHandle);
    OCPWMStart(pOCPWMHandle);

    /*Initialising variables that are needed for calculating the peak frequency*/
    int peakFrequency = 0;
    int peakFrequencyBin = 0;

    while (1) {
        /*Wait till the ADC has a new frame available*/
        while (ADCChannelIsBusy(pADCChannelHandle));

        /*Read in the Audio Samples from the ADC*/
        ADCChannelRead(pADCChannelHandle, frctAudioIn, FRAME_SIZE);

        /*Computing the FFT of the raw signal*/
        fourierTransform(FRAME_SIZE, compX, frctAudioIn);

        /*Removing the negative part of the FFT output (imaginary part) by zeroing it out*/
        filterNegativeFreq(FRAME_SIZE, compXfiltered, compX);

        /*Compute the square magnitude of the complex FFT output array so we have a Real output vetor*/
        SquareMagnitudeCplx(FRAME_SIZE / 2, &compXfiltered[0], &compXfiltered[0].real);

        /*Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy*/
        /*i.e., the largest spectral component*/
        VectorMax(FRAME_SIZE / 2, &compXfiltered[0].real, &peakFrequencyBin);

        /*Compute the frequency (in Hz) of the largest spectral component*/
        peakFrequency = peakFrequencyBin * (8000 / FRAME_SIZE);

        /*Uses the peak frequency variable to turn on the corresponding LEDs*/
        turnOnLEDs(peakFrequency);

        /* Used for checking whether the user wants to record */
        if (CheckSwitchS1() == PRESSED) {
            if (switchState == 0) {
                //startRecording(); Code works, but doesn't record much, only a fraction of a second
            } else if (switchState == 1) {
                int i = 0;
                for (i; i < (FRAME_SIZE)*5; i++) {
                    frctAudioOut[i] = 0;
                }
                switchState = 0;
                firstPartExecutedDecision = 0;
            }
        }
        
        /* Switch two is just used to toggle between different modes */
        if (CheckSwitchS2() == PRESSED) {
            if (switchState2 == 0) {
                switchState2 = 1;
            } else if (switchState2 == 1) {
                switchState2 = 2;
            } else if (switchState2 == 2) {
                switchState2 = 0;
            }
        }
        
        /* Checking whether the peak frequency is above 800 and if so calling the function playPureSignal() */
        if (peakFrequency >= 800) {
            playPureSignal(peakFrequency);
        } else if (switchState2 != 2) {
            int i = 0;
            for (i; i < FRAME_SIZE; i++) {
                if (switchState2 == 0) {
                    frctAudioOut[i] = frctAudioIn[i]; //Used for the mode that allows for outputting of the original signal
                } else if (switchState2 == 1) {
                    frctAudioOut[i] = 0; //Used for the mode that requests silence if the threshold has not been met
                }
            }
        }

        if (switchState2 == 2) {
            int i = 0;
            for (i; i < FRAME_SIZE; i++) {
                frctAudioOut[i] = 0;
            }
        }
        
        /* Outputting the pure signal or original sound or silence, depending on what's inside frctAudioOut*/
        while (OCPWMIsBusy(pOCPWMHandle));
        OCPWMWrite(pOCPWMHandle, frctAudioOut, FRAME_SIZE);
    }

     /*=============================================================================
     | Function used for recording the input signal, a snapshot of the frame
     | is stored inside the frctAudioOut array, this is done five times as that
     | was the largest possible size for frctAudioOut array as anything larger would
     | lead to exhausting the memory, the function records correctly but the recording
     | is not long enough, hence the code was retired as it requires more work.
     *===========================================================================*/
    void startRecording() {
        if (firstPartExecutedDecision == 0) {
            int i = 0;

            for (i; i < FRAME_SIZE; i++) {
                frctAudioOut[i] = frctAudioIn[i]*0.5;
            }
            firstPartExecutedDecision = 1;
        }

        if (firstPartExecutedDecision == 1) {
            int i = FRAME_SIZE;
            int iFrameSize = 0;
            for (i; i < (FRAME_SIZE)*2; i++) {
                frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5;
                iFrameSize++;
            }
            firstPartExecutedDecision = 2;
        }

        if (firstPartExecutedDecision == 2) {
            int i = (FRAME_SIZE)*2;
            int iFrameSize = 0;
            for (i; i < (FRAME_SIZE)*3; i++) {
                frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5;
                iFrameSize++;
            }
            firstPartExecutedDecision = 3;
        }

        if (firstPartExecutedDecision == 3) {
            int i = (FRAME_SIZE)*3;
            int iFrameSize = 0;
            for (i; i < (FRAME_SIZE)*4; i++) {
                frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5;
                iFrameSize++;
            }
            firstPartExecutedDecision = 4;
        }

        if (firstPartExecutedDecision == 4) {
            int i = (FRAME_SIZE)*4;
            int iFrameSize = 0;
            for (i; i < (FRAME_SIZE)*5; i++) {
                frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5;
                iFrameSize++;
            }
            firstPartExecutedDecision = -1;
            switchState = 1;
        }
    }
    /*=============================================================================
     | Function used to generate the pure signal using the createSimpleSignal()
     | function available in the modulate.h header - this function uses the peak
     | frequency handed through the parameter call to decide what signal to generate.
     | The output signal is stored inside the frctAudioOut array which is then
     | later used for the OCPWMWrite() function to output the sound.
     *===========================================================================*/
    void playPureSignal(int peakFrequency) {
        int simpleSignalFrequency = 0;
        if (peakFrequency <= 1600) {
            simpleSignalFrequency = 500;
            createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut);
        } else if (peakFrequency <= 2400) {
            simpleSignalFrequency = 800;
            createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut);
        } else if (peakFrequency <= 3200) {
            simpleSignalFrequency = 1000;
            createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut);
        } else if (peakFrequency <= 4000) {
            simpleSignalFrequency = 1500;
            createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut);
        }
    }