Example #1
0
void CLUInputStream::refill() {
	byte *in = _inbuf;
	int16 *out = _outbuf;

	_file->seek(_file_pos, SEEK_SET);

	uint len_left = _file->read(in, MIN((uint32)BUFFER_SIZE, _end_pos - _file->pos()));

	_file_pos = _file->pos();

	while (len_left > 0) {
		uint16 sample;

		if (_firstTime) {
			_firstTime = false;
			_prev = READ_LE_UINT16(in);
			sample = _prev;
			len_left -= 2;
			in += 2;
		} else {
			uint16 delta = GetCompressedAmplitude(*in) << GetCompressedShift(*in);
			if (GetCompressedSign(*in))
				sample = _prev - delta;
			else
				sample = _prev + delta;

			_prev = sample;
			len_left--;
			in++;
		}

		*out++ = (int16)sample;
	}

	_pos = _outbuf;
	_bufferEnd = out;
}
Example #2
0
void CompressSword2::execute() {
	int j;
	uint32 indexSize;
	uint32 totalSize;
	uint32 length;

	Common::Filename inpath(_inputPaths[0].path);
	Common::Filename &outpath = _outputPath;

	if (outpath.empty())
		// Extensions change between the in/out files, so we can use the same directory
		outpath = inpath;

	switch (_format) {
	case AUDIO_MP3:
		_audioOutputFilename = TEMP_MP3;
		outpath.setExtension(".cl3");
		break;
	case AUDIO_VORBIS:
		_audioOutputFilename = TEMP_OGG;
		outpath.setExtension(".clg");
		break;
	case AUDIO_FLAC:
		_audioOutputFilename = TEMP_FLAC;
		outpath.setExtension(".clf");
		break;
	default:
		throw ToolException("Unknown audio format");
		break;
	}

	_input.open(inpath, "rb");

	indexSize = _input.readUint32LE();
	totalSize = 12 * (indexSize + 1);

	if (_input.readUint32BE() != 0xfff0fff0) {
		error("This doesn't look like a cluster file");
	}

	_output_idx.open(TEMP_IDX, "wb");
	_output_snd.open(TEMP_DAT, "wb");

	_output_idx.writeUint32LE(indexSize);
	_output_idx.writeUint32BE(0xfff0fff0);
	_output_idx.writeUint32BE(0xfff0fff0);

	for (int i = 0; i < (int)indexSize; i++) {
		// Update progress, this loop is where most of the time is spent
		updateProgress(i, indexSize);

		uint32 pos;
		uint32 enc_length;

		_input.seek(8 * (i + 1), SEEK_SET);

		pos = _input.readUint32LE();
		length = _input.readUint32LE();

		if (pos != 0 && length != 0) {
			uint16 prev;

			Common::File f(TEMP_WAV, "wb");

			/*
			 * The number of decodeable 16-bit samples is one less
			 * than the length of the resource.
			 */

			length--;

			/*
			 * Back when this tool was written, encodeAudio() had
			 * no way of encoding 16-bit data, so it was simpler to
			 * output a WAV file.
			 */

			f.writeUint32BE(0x52494646);	/* "RIFF" */
			f.writeUint32LE(2 * length + 36);
			f.writeUint32BE(0x57415645);	/* "WAVE" */
			f.writeUint32BE(0x666d7420);	/* "fmt " */
			f.writeUint32LE(16);
			f.writeUint16LE(1);				/* PCM */
			f.writeUint16LE(1);				/* mono */
			f.writeUint32LE(22050);			/* sample rate */
			f.writeUint32LE(44100);			/* bytes per second */
			f.writeUint16LE(2);				/* basic block size */
			f.writeUint16LE(16);			/* sample width */
			f.writeUint32BE(0x64617461);	/* "data" */
			f.writeUint32LE(2 * length);

			_input.seek(pos, SEEK_SET);

			/*
			 * The first sample is stored uncompressed. Subsequent
			 * samples are stored as some sort of 8-bit delta.
			 */

			prev = _input.readUint16LE();

			f.writeUint16LE(prev);

			for (j = 1; j < (int)length; j++) {
				byte data;
				uint16 out;

				data = _input.readByte();
				if (GetCompressedSign(data))
					out = prev - (GetCompressedAmplitude(data) << GetCompressedShift(data));
				else
					out = prev + (GetCompressedAmplitude(data) << GetCompressedShift(data));

				f.writeUint16LE(out);
				prev = out;
			}

			f.close();

			encodeAudio(TEMP_WAV, false, -1, tempEncoded, _format);
			enc_length = append_to_file(_output_snd, tempEncoded);

			_output_idx.writeUint32LE(totalSize);
			_output_idx.writeUint32LE(length);
			_output_idx.writeUint32LE(enc_length);
			totalSize = totalSize + enc_length;
		} else {
			_output_idx.writeUint32LE(0);
			_output_idx.writeUint32LE(0);
			_output_idx.writeUint32LE(0);
		}
	}

	_output_snd.close();
	_output_idx.close();

	Common::File output(outpath, "wb");

	append_to_file(output, TEMP_IDX);
	append_to_file(output, TEMP_DAT);

	output.close();

	Common::removeFile(TEMP_DAT);
	Common::removeFile(TEMP_IDX);
	Common::removeFile(TEMP_MP3);
	Common::removeFile(TEMP_OGG);
	Common::removeFile(TEMP_FLAC);
	Common::removeFile(TEMP_WAV);
}