EQ Bars

edited May 2014

Hi, everyone! I’m a “TheAmazingAudioEngine” rookie and I would like to ask for assistance.
It’s necessary to display EQ bars the same way as this is done in this app - https://itunes.apple.com/us/app/eq-bars-audio-spectrum-analyzer/id622348339?mt=8
Please let me what I should start with or are there any available ready examples.
Your help is greatly appreciated!

Comments

  • Please help!:)

  • I don't have an answer sorry, but on a related question: has anybody implemented a guitar tuner using TAAE? I'm struggling to find code for a decent one, or even where to start really

  • edited May 2014

    Fourier analysis is what you need to use (specifically, the FFT). It's quite complicated DSP, though - this stuff isn't for the faint of heart, and delves quite deeply into maths.

    Take a look at this thread for some pointers and code:
    http://forum.theamazingaudioengine.com/discussion/277/the-frequency-spectrum-of-an-audio/p1

  • edited May 2014

    I use a slightly modified findDominantFrequency function from the example. A white noise is played for testing. The issue is that the received data has different values. Though the values should be the same for white noise, shouldn’t they?
    Check my function:

    static void audioCallback(id THISptr, AEAudioController *audioController, void *source, const AudioTimeStamp *time, UInt32 frames, AudioBufferList *audio) {
        FFT *THIS = (FFT*)THISptr;
        
        // Convert audio
        AEFloatConverterToFloatBufferList(THIS->_floatConverter, audio, THIS->_conversionBuffer, frames);
        
        // Get a pointer to the audio buffer that we can advance
        float *audioPtr = THIS->_conversionBuffer->mBuffers[0].mData;
        
        float *mag = NULL;
    
        findDominantFrequency(THIS, audioPtr, frames, mag);
    }
    
    static float findDominantFrequency(FFT *THIS, float *samples, UInt32 length, float *outMagnitude) {
        int32_t availableBytes;
        TPCircularBufferTail(&THIS->_fftBuffer, &availableBytes);
        
        UInt32 availableFrames = availableBytes/sizeof(float);
        if ( availableFrames+length > kProcessingBlockSize ) {
            // Throw away the excess frames
            int32_t discardBytes = MIN(availableFrames, availableBytes+length - kProcessingBlockSize) * sizeof(float);
            TPCircularBufferConsumeNoBarrier(&THIS->_fftBuffer, discardBytes);
        }
        
        // Add in the new frames
        TPCircularBufferProduceBytes(&THIS->_fftBuffer, samples, length * sizeof(float));
        
        float *buffer = (float*)TPCircularBufferTail(&THIS->_fftBuffer, &availableBytes);
        availableFrames = availableBytes / sizeof(float);
        
        // Wait till we have kProcessingBlockSize frames available to process
        if ( availableFrames < kProcessingBlockSize ) return 0;
        
        // Put our real signal into a split complex buffer, as required by the FFT
        vDSP_ctoz((COMPLEX*)buffer, 2, &THIS->_complexBuffer, 1, THIS->_nOver2);
        
        // Carry out a forward FFT
        vDSP_fft_zrip(THIS->_fftSetup, &THIS->_complexBuffer, 1, THIS->_log2n, FFT_FORWARD);
        
        // Determine the dominant frequency by taking the magnitude squared and
        // saving the bin which it resides in.
        NSMutableArray *values = [NSMutableArray array];
        
        float dominantFrequencyIntensity = 0;
        int bin = -1;
        int cutoff = kFrequencyCutoff / (44100.0/kProcessingBlockSize);
        for (int i=0; i_n && i < cutoff; i++) {
            float frequencyIntensity = magnitudeSquared(THIS->_complexBuffer.realp[i], THIS->_complexBuffer.imagp[i]);
    
            if (frequencyIntensity > dominantFrequencyIntensity) {
                dominantFrequencyIntensity = frequencyIntensity;
                bin = (i+1);
            }
            
            [values addObject:[NSNumber numberWithFloat:frequencyIntensity]];
        }
        
        //GET AVG VALUES
        NSMutableArray *result = [NSMutableArray array];
        
        int j = 0;
        int count = values.count/10;
        float value = 0;
        for (int i=0; i_fftBuffer, kProcessingBlockSize * sizeof(float));
        
        float frequency = bin * (44100.0/kProcessingBlockSize);
        
      //  *outMagnitude = dominantFrequencyIntensity;
        
        
        return frequency;
    }
    
    
  • White noise has a uniform frequency distribution - it has all frequencies within it, so that behaviour is as expected. You probably want to test this with a tone, or better yet, microphone input so you can whistle different tones and see the immediate output change.

Sign In or Register to comment.