コード例 #1
0
void PixarDemo2012::generateWaveforms()
{
    // DRAW MEM SPEHRES AND WAVEFORMS
    // Check init flag
    if ( mFft ) {

        // Get data in the frequency (transformed) and time domains
        float * freqData = mFft->getAmplitude();
        float * timeData = mFft->getData();
        int32_t dataSize = mFft->getBinSize();

        // Cast data size to float
        float dataSizef = (float)dataSize;

        // Get dimensions
        float scale = ( (float)getWindowWidth() - 20.0f ) / dataSizef;
        float windowHeight = (float)getWindowHeight();

        // Use polylines to depict time and frequency domains
        PolyLine<Vec2f> freqLine;
        PolyLine<Vec2f> timeLine;

        makeBall = 0.0f;
        float greatestFreq = 0.0;
        // Iterate through data
        for ( int32_t i = 0; i < dataSize; i++ ) {

            // Do logarithmic plotting for frequency domain
            float logSize = math<float>::log( dataSizef );
            float x = (float)( ( math<float>::log( (float)i ) / logSize ) * dataSizef );
            float y = math<float>::clamp( freqData[ i ] * ( x / dataSizef ) * ( math<float>::log( ( dataSizef - (float)i ) ) ), 0.0f, 2.0f );

            if (y > makeBall) makeBall = y;

            if(y > greatestFreq)
                greatestFreq = y;


            // Plot points on lines for tme domain
            freqLine.push_back( Vec2f(        x * scale + 10.0f,            -y * ( windowHeight - 20.0f ) * 1.75f + ( windowHeight - 10.0f ) ) );
            timeLine.push_back( Vec2f( (float)i * scale + 10.0f, timeData[ i ] * ( windowHeight - 20.0f ) * 0.25f + ( windowHeight * 0.25f + 10.0f ) ) );

        }
        //printf("%f\n", greatestFreq);
        theMindField.SetAmps(greatestFreq);
        // Draw signals
        if ( drawFFT ) {
            gl::draw( freqLine );
            gl::draw( timeLine );
        }

    }

}
コード例 #2
0
// Draw
void KissBasicApp::draw()
{

	// Clear screen
	gl::clear( ColorAf::black() );

	// Check init flag
	if ( mFft ) {

		// Get data in the frequency (transformed) and time domains
		float * freqData = mFft->getAmplitude();
		float * timeData = mFft->getData();
		int32_t dataSize = mFft->getBinSize();

		// Cast data size to float
		float dataSizef = (float)dataSize;

		// Get dimensions
		float scale = ( (float)getWindowWidth() - 20.0f ) / dataSizef;
		float windowHeight = (float)getWindowHeight();

		// Use polylines to depict time and frequency domains
		PolyLine<Vec2f> freqLine;
		PolyLine<Vec2f> timeLine;

		// Iterate through data
		for ( int32_t i = 0; i < dataSize; i++ ) {

			// Do logarithmic plotting for frequency domain
			float logSize = math<float>::log( dataSizef );
			float x = (float)( (math<float>::log( (float)i) / logSize ) * dataSizef );
			float y = math<float>::clamp( freqData[i] * ( x / dataSizef ) * ( math<float>::log( ( dataSizef - (float)i ) ) ), 0.0f, 2.0f );

			// Plot points on lines for tme domain
			freqLine.push_back( Vec2f(        x * scale + 10.0f,          -y   * ( windowHeight - 20.0f ) * 0.25f + ( windowHeight - 10.0f ) ) );
			timeLine.push_back( Vec2f( (float)i * scale + 10.0f, timeData[ i ] * ( windowHeight - 20.0f ) * 0.25f + ( windowHeight * 0.25f + 10.0f ) ) );

		}

		// Draw signals
		gl::draw( freqLine );
		gl::draw( timeLine );

	}

}
コード例 #3
0
// Runs update logic
void KissTempoApp::update() 
{

	// Don't evaluate right away or unrealistically 
	// high numbers will pop up
	if ( getElapsedSeconds() < 0.5 ) {
		return;
	}

	// Check if track is playing and has a PCM buffer available
	if ( mTrack && mTrack->isPlaying() && mTrack->isPcmBuffering() ) {

		// Get buffer
		mBuffer = mTrack->getPcmBuffer();
		if ( mBuffer && mBuffer->getInterleavedData() ) {

			// Get sample count
			uint32_t sampleCount = mBuffer->getInterleavedData()->mSampleCount;
			if ( sampleCount > 0 ) {

				// Kiss is not initialized
				if ( !mFft ) {

					// Initialize analyzer
					mFft = Kiss::create( sampleCount );

					// Set filter on FFT to calculate tempo based on beats
					mFft->setFilter( 0.2f, Kiss::Filter::LOW_PASS );

				}

				// Analyze data
				if ( mBuffer->getInterleavedData()->mData != 0 ) {

					// Set FFT data
					mInputData = mBuffer->getInterleavedData()->mData;
					mInputSize = mBuffer->getInterleavedData()->mSampleCount;
					mFft->setData( mInputData );

					// Get data
					mTimeData = mFft->getData();
					mDataSize = mFft->getBinSize();

					// Iterate through amplitude data
					for ( int32_t i = 0; i < mDataSize; i++, mSampleDistance++ ) {

						// Check value against threshold
						if ( mTimeData[ i ] >= mThreshold ) {

							// Determine neighbor range
							int32_t start = math<int32_t>::max( i - mNeighbors, 0 );
							int32_t end = math<int32_t>::min( i + mNeighbors, mDataSize - 1 );

							// Compare this value with neighbors to find peak
							bool peak = true;
							for ( int32_t j = start; j < end; j++ ) {
								if ( j != i && mTimeData[ i ] <= mTimeData[ j ] ) {
									peak = false;
									break;
								}
							}

							// This is a peak
							if ( peak ) {

								// Add distance between this peak and last into the 
								// list. Just note position if this is the first peak.
								if ( mFirstPeak >= 0 ) {
									mPeakDistances.push_back( mSampleDistance );
								} else {
									mFirstPeak = mSampleDistance;
								}
							
								// Reset distance counter
								mSampleDistance = 0;

							}

						}

					}

				}

			}

			// We have multiple peaks to compare
			if ( mPeakDistances.size() > 1 ) {

				// Add distances
				int32_t total = 0;
				uint32_t peakCount = mPeakDistances.size();
				for ( uint32_t i = 0; i < peakCount; i++ ) {
					total += mPeakDistances[ i ];
				}

				// Determine tempo based on average peak distance
				mTempo = total > 0 ? ( 44100.0f / ( (float)total / (float)mPeakDistances.size() ) ) * 60.0f / 1000.0f : 0.0f;

			}

			// Get current window height
			int32_t windowHeight = getWindowHeight() / 8;

			// Add up values, combine input and filtered values
			// to emphasize bass
			float total = 0.0f;
			for ( int32_t i = 0; i < mDataSize; i++ ) {
				if ( i * 8 < mInputSize ) {
					total += mTimeData[ i ] * 2.0f * mInputData[ i * 8 ];
				}
			}
		
			// Add average to drawing line
			mWaveform.push_back( total / (float)mDataSize );

			// Remove points when vector is wider than screen
			while ( mWaveform.size() >= (uint32_t)windowHeight ) {
				mWaveform.erase( mWaveform.begin() );
			}

		}

	}

}