Beispiel #1
0
int32 McmpMgr::decompressSample(int32 offset, int32 size, byte **comp_final) {
	int32 i, final_size, output_size;
	int skip, first_block, last_block;

	if (!_file) {
		error("McmpMgr::decompressSampleByName() File is not open!");
		return 0;
	}

	first_block = offset / 0x2000;
	last_block = (offset + size - 1) / 0x2000;
	skip = offset % 0x2000;

	// Clip last_block by the total number of blocks (= "comp items")
	if ((last_block >= _numCompItems) && (_numCompItems > 0))
		last_block = _numCompItems - 1;

	int32 blocks_final_size = 0x2000 * (1 + last_block - first_block);
	*comp_final = (byte *)malloc(blocks_final_size * sizeof(byte));
	final_size = 0;

	for (i = first_block; i <= last_block; i++) {
		if (_lastBlock != i) {
			// hack: two more zero bytes at the end of input buffer
			_compInput[_compTable[i].compSize] = 0;
			_compInput[_compTable[i].compSize + 1] = 0;
			_file->seek(_compTable[i].offset, SEEK_SET);
			_file->read(_compInput, _compTable[i].compSize);
			decompressVima(_compInput, (int16 *)_compOutput, _compTable[i].decompSize, imuseDestTable);
			_outputSize = _compTable[i].decompSize;
			if (_outputSize > 0x2000) {
				error("McmpMgr::decompressSample() _outputSize: %d", _outputSize);
			}
			_lastBlock = i;
		}

		output_size = _outputSize - skip;

		if ((output_size + skip) > 0x2000) // workaround
			output_size -= (output_size + skip) - 0x2000;

		if (output_size > size)
			output_size = size;

		assert(final_size + output_size <= blocks_final_size);

		memcpy(*comp_final + final_size, _compOutput + skip, output_size);
		final_size += output_size;

		size -= output_size;
		assert(size >= 0);
		if (size == 0)
			break;

		skip = 0;
	}

	return final_size;
}
Beispiel #2
0
void SmushDecoder::handleWave(const byte *src, uint32 size) {
	int16 *dst = (int16 *) malloc(size * _channels * sizeof(int16));
	decompressVima(src, dst, size * _channels * 2, smushDestTable);

	int flags = Audio::FLAG_16BITS;
	if (_channels == 2)
		flags |= Audio::FLAG_STEREO;

	if (!_stream) {
		_stream = Audio::makeQueuingAudioStream(_freq, (_channels == 2));
		g_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, _stream);
	}
	if (g_system->getMixer()->isReady()) {
		_stream->queueBuffer((byte *)dst, size * _channels * 2, DisposeAfterUse::YES, flags);
	} else {
		free(dst);
	}
}