Example #1
0
bool FLACStream::seek(const Timestamp &where) {
	_sampleCache.bufFill = 0;
	_sampleCache.bufReadPos = NULL;
	// FLAC uses the sample pair number, thus we always use "false" for the isStereo parameter
	// of the convertTimeToStreamPos helper.
	return seekAbsolute((FLAC__uint64)convertTimeToStreamPos(where, getRate(), false).totalNumberOfFrames());
}
Example #2
0
int FlacInputStream::readBuffer(int16 *buffer, const int numSamples) {
	const uint numChannels = getChannels();

	if (numChannels == 0) {
		warning("FlacInputStream: Stream not sucessfully initialised, cant playback");
		return -1; // streaminfo wasnt read!
	}

	assert(numSamples % numChannels == 0); // must be multiple of channels!
	assert(buffer != NULL);
	assert(_outBuffer == NULL);
	assert(_requestedSamples == 0);

	_outBuffer = buffer;
	_requestedSamples = numSamples;

	// If there is still data in our buffer from the last time around,
	// copy that first.
	if (_sampleCache.bufFill > 0) {
		assert(_sampleCache.bufReadPos >= _sampleCache.bufData);
		assert(_sampleCache.bufFill % numChannels == 0);

		const uint copySamples = MIN((uint)numSamples, _sampleCache.bufFill);
		memcpy(buffer, _sampleCache.bufReadPos, copySamples*sizeof(buffer[0]));

		_outBuffer = buffer + copySamples;
		_requestedSamples = numSamples - copySamples;
		_sampleCache.bufReadPos += copySamples;
		_sampleCache.bufFill -= copySamples;
	}

	bool decoderOk = true;

	FLAC__StreamDecoderState state = getStreamDecoderState();

	// Keep poking FLAC to process more samples until we completely satisfied the request
	// respectively until we run out of data.
	while (!_lastSampleWritten && _requestedSamples > 0 && state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) {
		assert(_sampleCache.bufFill == 0);
		assert(_requestedSamples % numChannels == 0);
		processSingleBlock();
		state = getStreamDecoderState();

		if (state == FLAC__STREAM_DECODER_END_OF_STREAM) {
			_lastSampleWritten = true;
		}

		// 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);
			state = getStreamDecoderState();
		}
	}

	// Error handling
	switch (state) {
	case FLAC__STREAM_DECODER_END_OF_STREAM:
		_lastSampleWritten = true;
		break;
	case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
		break;
	default:
		decoderOk = false;
		warning("FlacInputStream: An error occured while decoding. DecoderState is: %s",
			FLAC__StreamDecoderStateString[getStreamDecoderState()]);
	}

	// Compute how many samples we actually produced
	const int samples = (int)(_outBuffer - buffer);
	assert(samples % numChannels == 0);

	_outBuffer = NULL; // basically unnecessary, only for the purpose of the asserts
	_requestedSamples = 0; // basically unnecessary, only for the purpose of the asserts

	return decoderOk ? samples : -1;
}