Пример #1
0
void BufferedAudioSourceThread::run()
{
    std::vector<float> tempBuffer;
    
	while(1)
	{
		mReadMore.wait();

		if(shouldThreadExit())
			break;

		
		{ // create a local scope for our locking object
			RScopedLock l(&mLock);
		
			for(UInt32 i = 0; i < mSources.size(); ++i)
			{
				BufferedAudioSource *pSource = mSources[i];
				
				pSource->mLock.lock();

				Int64 totalFrames = pSource->getSampleRate() * SECONDS_TO_BUFFER;
				Int64 framesThreshold = totalFrames / 2; // 
				Int64 availableFrames = pSource->mBuffer.size() / pSource->getNumChannels();

				pSource->mLock.unlock();
				
				if(availableFrames <= framesThreshold)
				{
					Int64 numFrames = totalFrames - availableFrames;                
					Int64 framesToRead = numFrames;
					Int64 frames = 0;
					tempBuffer.resize(numFrames * pSource->getNumChannels());
					float *pBuffer = &tempBuffer[0];

					// keep track of last known version when starting to buffer
					// to discard any previously buffered data in case source
					// changed position. This avoids having to keep a lock
					// while buffering data.
					int lastVersion = pSource->getPositionVersion();

					while(framesToRead > 0 && !pSource->isEOF())
					{
                        int currentVersion = 0;
						frames = pSource->decodeData(pBuffer, framesToRead, currentVersion);

						// check if version changed since we started buffering
						// and discard everything we've buffered before if so
                        if (currentVersion != lastVersion) {
                            tempBuffer.erase(tempBuffer.begin(), tempBuffer.begin() + ((numFrames - framesToRead) * pSource->getNumChannels()));
                            tempBuffer.resize(numFrames * pSource->getNumChannels());
                            pBuffer = &tempBuffer[0];
                            framesToRead = numFrames;
                        }
						framesToRead -= frames;
						pBuffer += frames * pSource->getNumChannels();
                        lastVersion = currentVersion;
					}

					// Now write the data back to the buffer
					Int64 framesRead = numFrames - framesToRead;
					if(framesRead > 0)
					{
						pSource->mLock.lock();
						pSource->mBuffer.putData(&tempBuffer[0], framesRead * pSource->getNumChannels());
						pSource->mLock.unlock();
					}
				}
			}
		}
		
	}
}
Пример #2
0
void BufferedAudioSourceThread::run()
{
    std::vector<float> tempBuffer;
    
	while(1)
	{
		mReadMore.wait();

		if(shouldThreadExit())
			break;

		mLock.lock();

		for(UInt32 i = 0; i < mSources.size(); ++i)
		{
			BufferedAudioSource *pSource = mSources[i];
            
            pSource->mLock.lock();

			Int64 totalFrames = pSource->getSampleRate() * SECONDS_TO_BUFFER;
			Int64 availableFrames = pSource->mBuffer.size() / pSource->getNumChannels();

            pSource->mLock.unlock();
            
			if(availableFrames < totalFrames)
			{
				Int64 numFrames = totalFrames - availableFrames;                
				Int64 framesToRead = numFrames;
				Int64 frames = 0;
                tempBuffer.resize(numFrames * pSource->getNumChannels());
                float *pBuffer = &tempBuffer[0];
				do
				{
					frames = pSource->decodeData(pBuffer, framesToRead);
					framesToRead -= frames;
					pBuffer += frames * pSource->getNumChannels();
				}
				while(framesToRead > 0 && !pSource->isEOF());

                // Now write the data back to the buffer
				Int64 framesRead = numFrames - framesToRead;
				if(framesRead > 0)
				{
	                pSource->mLock.lock();
                
		            int fillPosition = pSource->mBuffer.size();
			        Int64 totalSamples = pSource->mBuffer.size() + framesRead * pSource->getNumChannels();
				    pSource->mBuffer.resize(totalSamples);
					memcpy(&pSource->mBuffer[fillPosition], &tempBuffer[0], sizeof(float) * framesRead * pSource->getNumChannels());

					pSource->mLock.unlock();
				}
                
                // Check if we've reached the end
/*
				double loopStart;
				double loopEnd;
				pSource->getLoopPoints(loopStart, loopEnd);
				Int64 loopEndFrame = pSource->convertSecondsToSamples(pSource->mLoopEnd);

                if(pSource->isLooping() && pSource->mCurrentFrame >= loopEndFrame && loopEndFrame > 0)
					pSource->setPosition(loopStart);


				if(pSource->isEOF() || (pSource->mCurrentFrame >= loopEndFrame && loopEndFrame > 0))
                {
                    if(pSource->isLooping())
                        // Reset the buffering position and keep on going...
                        pSource->setPosition(loopStart);
//                    else
//                        // We didn't fill the whole buffer, so resize appropriately
//                        pSource->mBuffer.resize(availableFrames + numFrames - framesToRead);
                }
*/
			}

		}

        mLock.unlock();
	}
}