Simplified version of FFT code - drives on-board LED as a "Colour Organ".

Dependencies:   FastAnalogIn NVIC_set_all_priorities mbed-dsp mbed

Fork of KL25Z_FFT_Demo_tony by Tony Abbey

Revision:
1:7421267b0777
Parent:
0:b8c9dffbbe7e
Child:
2:177596541c8d
diff -r b8c9dffbbe7e -r 7421267b0777 main.cpp
--- a/main.cpp	Tue Jun 17 14:03:36 2014 +0000
+++ b/main.cpp	Tue Nov 15 22:16:24 2016 +0000
@@ -9,10 +9,11 @@
 #include "arm_math.h"
 #include "arm_const_structs.h"
 #include "FastAnalogIn.h"
+#include <string>
 
+FastAnalogIn   Audio(PTC2);
 Serial pc(USBTX, USBRX);
 
-FastAnalogIn   Audio(PTC2);
 
 //#define RGBW_ext // Disable this line when you want to use the KL25Z on-board RGB LED.
 
@@ -44,20 +45,12 @@
 //   Max allowed SAMPLE_RATE_HZ is 40000
 //   Max allowed FFT_SIZE is 64
 ////////////////////////////////////////////////////////////////////////////////
-
-int SLOWDOWN = 4;                       // Create an optical delay in spectrumLoop - useful when only one RGB led is used.
-                                        // Only active when nonzero.
                                         // A value >= 1000 and <= 1000 + PIXEL_COUNT fixes the output to a single frequency
                                         // window = a single color.
-int SAMPLE_RATE_HZ = 20000;             // Sample rate of the audio in hertz.
-float SPECTRUM_MIN_DB = 20.0;           // Audio intensity (in decibels) that maps to low LED brightness.
-float SPECTRUM_MAX_DB = 80.0;           // Audio intensity (in decibels) that maps to high LED brightness.
-int LEDS_ENABLED = 1;                   // Control if the LED's should display the spectrum or not.  1 is true, 0 is false.
+int SAMPLE_RATE_HZ = 1000;             // Sample rate of the audio in hertz.
+
                                         // Useful for turning the LED display on and off with commands from the serial port.
-const int FFT_SIZE = 64;                // Size of the FFT.
-const int PIXEL_COUNT = 3;             // Number of pixels (RGB LED).  You should be able to increase this without
-                                        // any other changes to the program.
-const int MAX_CHARS = 65;               // Max size of the input command buffer
+const int FFT_SIZE = 256;                // Size of the FFT.
 
 ////////////////////////////////////////////////////////////////////////////////
 // INTERNAL STATE
@@ -68,43 +61,11 @@
 float samples[FFT_SIZE*2];
 float magnitudes[FFT_SIZE];
 int sampleCounter = 0;
-char commandBuffer[MAX_CHARS];
-float frequencyWindow[PIXEL_COUNT+1];
-float hues[PIXEL_COUNT];
-bool commandRecv = 0;
-////////////////////////////////////////////////////////////////////////////////
-// UTILITY FUNCTIONS
-////////////////////////////////////////////////////////////////////////////////
 
-void rxisr() {
-    char c = pc.getc();
-    // Add any characters that aren't the end of a command (semicolon) to the input buffer.
-    if (c != ';') {
-        c = toupper(c);
-        strncat(commandBuffer, &c, 1);
-    } else {
-        // Parse the command because an end of command token was encountered.
-        commandRecv = 1;
-    }
-}
+int arrayPosition;
+int maxFrequencyValue;
 
-// Compute the average magnitude of a target frequency window vs. all other frequencies.
-void windowMean(float* magnitudes, int lowBin, int highBin, float* windowMean, float* otherMean)
-{
-    *windowMean = 0;
-    *otherMean = 0;
-    // Notice the first magnitude bin is skipped because it represents the
-    // average power of the signal.
-    for (int i = 1; i < FFT_SIZE/2; ++i) {
-        if (i >= lowBin && i <= highBin) {
-            *windowMean += magnitudes[i];
-        } else {
-            *otherMean += magnitudes[i];
-        }
-    }
-    *windowMean /= (highBin - lowBin) + 1;
-    *otherMean /= (FFT_SIZE / 2 - (highBin - lowBin));
-}
+int FFTFrequency;
 
 // Convert a frequency to the appropriate FFT bin it will fall within.
 int frequencyToBin(float frequency)
@@ -114,78 +75,6 @@
 }
 
 
-////////////////////////////////////////////////////////////////////////////////
-// SPECTRUM DISPLAY FUNCTIONS
-///////////////////////////////////////////////////////////////////////////////
-
-void spectrumSetup()
-{
-    // Set the frequency window values by evenly dividing the possible frequency
-    // spectrum across the number of neo pixels.
-    float windowSize = (SAMPLE_RATE_HZ / 2.0) / float(PIXEL_COUNT);
-    for (int i = 0; i < PIXEL_COUNT+1; ++i) {
-        frequencyWindow[i] = i*windowSize;
-    }
- 
-}
-
-void spectrumLoop()
-{
-    // Update each LED based on the intensity of the audio
-    // in the associated frequency window.
-    static int SLrpt = 0, SLpixcnt = 0;
-    int SLpixend = 0;
-    float intensity, otherMean;
-    if(SLOWDOWN != 0)
-    {
-        if(SLOWDOWN >= 1000)
-        {
-            if(SLOWDOWN <= (1000 + PIXEL_COUNT-1))
-            {
-                SLpixcnt = SLOWDOWN - 1000;
-                SLrpt = 0;
-                SLpixend = SLpixcnt + 1;
-            }
-            else
-                SLOWDOWN = 0;
-        }
-        else
-        {
-            SLrpt++;
-            if (SLrpt >= SLOWDOWN)
-            {
-                SLrpt = 0;
-                SLpixcnt = SLpixcnt < PIXEL_COUNT-1 ? ++SLpixcnt : 0;
-            }
-            SLpixend = SLpixcnt + 1;
-        }
-    }
-    else
-    {
-        SLpixcnt = 0;
-        SLrpt = 0;
-        SLpixend = PIXEL_COUNT;
-    }
-    for (int i = SLpixcnt; i < SLpixend; ++i) {
-        windowMean(magnitudes,
-                   frequencyToBin(frequencyWindow[i]),
-                   frequencyToBin(frequencyWindow[i+1]),
-                   &intensity,
-                   &otherMean);
-        // Convert intensity to decibels.
-        intensity = 20.0*log10(intensity);
-        // Scale the intensity and clamp between 0 and 1.0.
-        intensity -= SPECTRUM_MIN_DB;
-        intensity = intensity < 0.0 ? 0.0 : intensity;
-        intensity /= (SPECTRUM_MAX_DB-SPECTRUM_MIN_DB);
-        intensity = intensity > 1.0 ? 1.0 : intensity;
-        hues[i]=intensity;
-    }
-    rled=1.0-hues[0] ;  // onboard LED is common anode so inversion needed
-    gled=1.0-hues[1];
-    bled=1.0-hues[2];
-}
-
 
 ////////////////////////////////////////////////////////////////////////////////
 // SAMPLING FUNCTIONS
@@ -217,90 +106,33 @@
     return sampleCounter >= FFT_SIZE*2;
 }
 
-
 ////////////////////////////////////////////////////////////////////////////////
-// COMMAND PARSING FUNCTIONS
-// These functions allow parsing simple commands input on the serial port.
-// Commands allow reading and writing variables that control the device.
-//
-// All commands must end with a semicolon character.
-//
-// Example commands are:
-// GET SAMPLE_RATE_HZ;
-// - Get the sample rate of the device.
-// SET SAMPLE_RATE_HZ 400;
-// - Set the sample rate of the device to 400 hertz.
-//
+// FREQUENCY 
 ////////////////////////////////////////////////////////////////////////////////
 
-void parseCommand(char* command)
+
+void set_ArrayPosition()
 {
-    if (strcmp(command, "GET MAGNITUDES") == 0) {
-        for (int i = 0; i < FFT_SIZE; ++i) {
-            printf("%f\r\n", magnitudes[i]);
-        }
-    } else if (strcmp(command, "GET SAMPLES") == 0) {
-        for (int i = 0; i < FFT_SIZE*2; i+=2) {
-            printf("%f\r\n", samples[i]);
-        }
-    } else if (strcmp(command, "GET FFT_SIZE") == 0) {
-        printf("%d\r\n", FFT_SIZE);
-    } else if (strcmp(command, "GET SAMPLE_RATE_HZ") == 0) {
-        printf("%d\r\n", SAMPLE_RATE_HZ);
-    } else if (strstr(command, "SET SAMPLE_RATE_HZ") != NULL) {
-        SAMPLE_RATE_HZ = (typeof(SAMPLE_RATE_HZ)) atof(command+(sizeof("SET SAMPLE_RATE_HZ")-1));
-    } else if (strcmp(command, "GET LEDS_ENABLED") == 0) {
-        printf("%d\r\n", LEDS_ENABLED);
-    } else if (strstr(command, "SET LEDS_ENABLED") != NULL) {
-        LEDS_ENABLED = (typeof(LEDS_ENABLED)) atof(command+(sizeof("SET LEDS_ENABLED")-1));
-    } else if (strcmp(command, "GET SPECTRUM_MIN_DB") == 0) {
-        printf("%f\r\n", SPECTRUM_MIN_DB);
-    } else if (strstr(command, "SET SPECTRUM_MIN_DB") != NULL) {
-        SPECTRUM_MIN_DB = (typeof(SPECTRUM_MIN_DB)) atof(command+(sizeof("SET SPECTRUM_MIN_DB")-1));
-    } else if (strcmp(command, "GET SPECTRUM_MAX_DB") == 0) {
-        printf("%f\r\n", SPECTRUM_MAX_DB);
-    } else if (strstr(command, "SET SPECTRUM_MAX_DB") != NULL) {
-        SPECTRUM_MAX_DB = (typeof(SPECTRUM_MAX_DB)) atof(command+(sizeof("SET SPECTRUM_MAX_DB")-1));
-    } else if (strcmp(command, "GET SLOWDOWN") == 0) {
-        printf("%d\r\n", SLOWDOWN);
-    } else if (strstr(command, "SET SLOWDOWN") != NULL) {
-        SLOWDOWN = (typeof(SLOWDOWN)) atoi(command+(sizeof("SET SLOWDOWN")-1));
-    }
-
-    // Update spectrum display values if sample rate was changed.
-    if (strstr(command, "SET SAMPLE_RATE_HZ ") != NULL) {
-        spectrumSetup();
-    } else if (strcmp(command, "GET HUES") == 0) {
-        for (int i = 0; i < PIXEL_COUNT; ++i) {
-            printf("%f\r\n", hues[i]);
-        }
-    }
+    float maxValue = 0.0;
     
-
-    // Turn off the LEDs if the state changed.
-    if (LEDS_ENABLED == 0) {
-    }
-}
-
-void parserLoop()
-{
-    // Process any incoming characters from the serial port
-    while (pc.readable()) {
-        char c = pc.getc();
-        // (doesnt work!) printf("%c",c); // echo characters typed
-        // Add any characters that aren't the end of a command (semicolon) to the input buffer.
-        if (c != ';') {
-            c = toupper(c);
-            strncat(commandBuffer, &c, 1);
-        } else {
-            // Parse the command because an end of command token was encountered.
-            parseCommand(commandBuffer);
-            // Clear the input buffer
-            memset(commandBuffer, 0, sizeof(commandBuffer));
+    for(int counter=0; counter < FFT_SIZE; counter++)
+    {
+        if(magnitudes[counter] > maxValue){
+            maxValue = magnitudes[counter];
+            arrayPosition = counter+1;
         }
     }
 }
 
+int get_FFTFrequency()
+{
+    maxFrequencyValue = SAMPLE_RATE_HZ/2;
+    
+    set_ArrayPosition();
+    
+    return (maxFrequencyValue*arrayPosition)/FFT_SIZE;
+    
+}
 ////////////////////////////////////////////////////////////////////////////////
 // MAIN FUNCTION
 ////////////////////////////////////////////////////////////////////////////////
@@ -309,15 +141,6 @@
 {
     NVIC_set_all_irq_priorities(1);
     NVIC_SetPriority(UART0_IRQn, 0);
-    // Set up serial port.
-    pc.baud (38400);
-    pc.attach(&rxisr);
-
-    // Clear the input command buffer
-    memset(commandBuffer, 0, sizeof(commandBuffer));
-
-    // Initialize spectrum display
-    spectrumSetup();
 
     // Begin sampling audio
     samplingBegin();
@@ -354,31 +177,23 @@
         break;
     }
 
-    while(1) {
+    while(true) {
         // Calculate FFT if a full sample is available.
         if (samplingIsDone()) {
             // Run FFT on sample data.
             arm_cfft_f32(S, samples, 0, 1);
             // Calculate magnitude of complex numbers output by the FFT.
             arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE);
-
-            if (LEDS_ENABLED == 1) {
-                spectrumLoop();
-            }
-
+            //Obtaining the value of the frequency 
+            FFTFrequency = get_FFTFrequency();
+            
+            for(int i=0; 
+            pc.printf("Frequency is: ", FFTFrequency);
+            pc.printf("\r\n [");
+            
             // Restart audio sampling.
             samplingBegin();
-        printf("this will make it work  ");
-        }
-
-        // Parse any pending commands.
-        if(commandRecv) {
-//            pc.attach(NULL);
-            parseCommand(commandBuffer);
-            commandRecv = 0;
-            // Clear the input buffer
-            memset(commandBuffer, 0, sizeof(commandBuffer));
-//            pc.attach(&rxisr);
-        }
+        } 
     }
+    
 }