void PixarDemo2012::update() { if ( mFullScreen != isFullScreen() ) { setFullScreen(mFullScreen); // mCamera->setAspectRatio(getWindowAspectRatio()); // mySurface = cairo::SurfaceImage(getWindowWidth(),getWindowHeight(),true); if ( isFullScreen() == true ) { hideCursor(); } else { showCursor(); } } mTime += 0.01f; float kFudge = 0.1; // ten times our step if(mAutoCut && mTime > mCuts[mCurrentCut] && mTime < mCuts[mCurrentCut] + kFudge ) { doFade = true; mCurrentCut = mCurrentCut + 1; if(mCurrentCut >= mCuts.size()) { mCurrentCut = mCuts.size()-1; } } mParticleController.update(); if ( drawTitle ) { theTitle.Update(); } if ( drawCloth ) { theCloth.Update( ); } if ( drawCubes ) { theCubes.Update(); } if ( drawMindField ) { theMindField.Update(); } // Check if track is playing and has a PCM buffer available if ( 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 ) { // Initialize analyzer if ( !mFft ) { mFft = Kiss::create( sampleCount ); } // Analyze data if ( mBuffer->getInterleavedData()->mData != 0 ) { mFft->setData( mBuffer->getInterleavedData()->mData ); } } } } }
// 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() ); } } } }