[Scummvm-cvs-logs] SF.net SVN: scummvm: [25833] scummvm/trunk/sound/flac.cpp

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Sat Feb 24 23:14:49 CET 2007


Revision: 25833
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25833&view=rev
Author:   fingolfin
Date:     2007-02-24 14:14:48 -0800 (Sat, 24 Feb 2007)

Log Message:
-----------
Add looping support to the FLAC decoder

Modified Paths:
--------------
    scummvm/trunk/sound/flac.cpp

Modified: scummvm/trunk/sound/flac.cpp
===================================================================
--- scummvm/trunk/sound/flac.cpp	2007-02-24 21:25:46 UTC (rev 25832)
+++ scummvm/trunk/sound/flac.cpp	2007-02-24 22:14:48 UTC (rev 25833)
@@ -292,7 +292,6 @@
 	const bool result = (0 != ::FLAC__stream_decoder_seek_absolute(_decoder, sample));
 #endif
 	if (result) {
-		_sampleCache.bufFill = 0;
 		_lastSampleWritten = (_lastSample != 0 && sample >= _lastSample); // only set if we are SURE
 	}
 	return result;
@@ -339,6 +338,13 @@
 			assert(_sampleCache.bufFill == 0);
 			assert(_requestedSamples % numChannels == 0);
 			processSingleBlock();
+
+			// If we reached the end of the stream, and looping is enabled: Try to rewind
+			if (_lastSampleWritten && _numLoops != 1) {
+				if (_numLoops != 0)
+					_numLoops--;
+				seekAbsolute(_firstSample);
+			}
 		}
 
 		// Error handling
@@ -565,7 +571,8 @@
 	assert(frame->header.bits_per_sample == _streaminfo.bits_per_sample);
 	assert(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER || _streaminfo.min_blocksize == _streaminfo.max_blocksize);
 
-	assert(_sampleCache.bufFill == 0); // we dont append data
+	// We require that either the sample cache is empty, or that no samples were requested
+	assert(_sampleCache.bufFill == 0 || _requestedSamples == 0);
 
 	uint numSamples = frame->header.blocksize;
 	const uint numChannels = getChannels();
@@ -576,20 +583,21 @@
 	const FLAC__uint64 firstSampleNumber = (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER) ?
 		frame->header.number.sample_number : (static_cast<FLAC__uint64>(frame->header.number.frame_number)) * _streaminfo.max_blocksize;
 
+	// Check whether we are about to reach beyond the last sample we are supposed to play.
 	if (_lastSample != 0 && firstSampleNumber + numSamples >= _lastSample) {
 		numSamples = (uint)(firstSampleNumber >= _lastSample ? 0 : _lastSample - firstSampleNumber);
-		_requestedSamples = MIN(_requestedSamples, numSamples * numChannels);
 		_lastSampleWritten = true;
 	}
 
+	// The value in _requestedSamples counts raw samples, so if there are more than one
+	// channel, we have to multiply the number of available sample "pairs" by numChannels
 	numSamples *= numChannels;
 
-	const FLAC__int32 *inChannels[MAX_OUTPUT_CHANNELS] = { buffer[0] }; // one channel is a given...
-	for (uint i = 1; i < numChannels; ++i)
+	const FLAC__int32 *inChannels[MAX_OUTPUT_CHANNELS];
+	for (uint i = 0; i < numChannels; ++i)
 		inChannels[i] = buffer[i];
 
-
-	// writing DIRECTLY to the Buffer ScummVM provided
+	// write the incoming samples directly into the buffer provided to us by the mixer
 	if (_requestedSamples > 0) {
 		assert(_requestedSamples % numChannels == 0);
 		assert(_outBuffer != NULL);
@@ -604,17 +612,16 @@
 		_outBuffer += copySamples;
 	}
 
-	// verify that the buffer fits
-	if (numSamples > BUFFER_SIZE) {
-		warning("FlacInputStream: write buffer is too small: %d bytes available, %d bytes needed", BUFFER_SIZE,numSamples); 
-		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
-	}
+	// Write all remaining samples (i.e. those which didn't fit into the mixer buffer)
+	// into the sample cache.
+	if (_sampleCache.bufFill == 0)
+		_sampleCache.bufReadPos = _sampleCache.bufData;
+	const uint cacheSpace = (_sampleCache.bufData + BUFFER_SIZE) - (_sampleCache.bufReadPos + _sampleCache.bufFill);
+	assert(numSamples <= cacheSpace);
+	(*_methodConvertBuffers)(_sampleCache.bufReadPos + _sampleCache.bufFill, inChannels, numSamples, numChannels, numBits);
 
-	(*_methodConvertBuffers)(_sampleCache.bufData, inChannels, numSamples, numChannels, numBits);
+	_sampleCache.bufFill += numSamples;
 
-	_sampleCache.bufFill = numSamples;
-	_sampleCache.bufReadPos = _sampleCache.bufData;
-
 	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
 }
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list