RewindableAudioStream *XACTWaveBank_ASCII::getWave(size_t index) const {
	if (index >= _waves.size())
		throw Common::Exception("XACTWaveBank_ASCII::getWave(): Index out of range (%s >= %s)",
		                        Common::composeString(index).c_str(),
		                        Common::composeString(_waves.size()).c_str());

	const Wave &wave = _waves[index];

	std::unique_ptr<Common::SeekableReadStream> dataStream(ResMan.getResource(wave.name, Aurora::kFileTypeOGG));
	if (!dataStream)
		throw Common::Exception("XACTWaveBank_ASCII::getWave(): No such resource \"%s\"", wave.name.c_str());

#ifdef ENABLE_VORBIS
	return makeVorbisStream(dataStream.release(), true);
#else
	throw Common::Exception("XACTWaveBank_ASCII::getWave(): Vorbis decoding disabled when building without libvorbis");
#endif
}
Exemple #2
0
AudioStream *SoundManager::makeAudioStream(Common::SeekableReadStream *stream) {
	bool isMP3 = false;
	uint32 tag = stream->readUint32BE();

	if (tag == 0xfff360c4) {
		// Modified WAVE file (used in streamsounds folder, at least in KotOR 1/2)
		stream = new Common::SeekableSubReadStream(stream, 0x1D6, stream->size(), true);

	} else if (tag == MKTAG('R', 'I', 'F', 'F')) {
		stream->seek(12);
		tag = stream->readUint32BE();

		if (tag != MKTAG('f', 'm', 't', ' '))
			throw Common::Exception("Broken WAVE file");

		// Skip fmt chunk
		stream->skip(stream->readUint32LE());
		tag = stream->readUint32BE();

		while ((tag == MKTAG('f', 'a', 'c', 't')) || (tag == MKTAG('P', 'A', 'D', ' ')) ||
		       (tag == MKTAG('c', 'u', 'e', ' ')) || (tag == MKTAG('L', 'I', 'S', 'T')) ||
		       (tag == MKTAG('s', 'm', 'p', 'l'))) {
			// Skip useless chunks
			stream->skip(stream->readUint32LE());
			tag = stream->readUint32BE();
		}

		if (tag != MKTAG('d', 'a', 't', 'a'))
			throw Common::Exception("Found invalid tag in WAVE file: %x", tag);

		uint32 dataSize = stream->readUint32LE();
		if (dataSize == 0) {
			isMP3 = true;
			stream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->size(), true);
		} else
			// Just a regular WAVE
			stream->seek(0);

	} else if ((tag                    == MKTAG('B', 'M', 'U', ' ')) &&
	           (stream->readUint32BE() == MKTAG('V', '1', '.', '0'))) {

		// BMU files: MP3 with extra header
		isMP3 = true;
		stream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->size(), true);

	} else if (tag == MKTAG('O', 'g', 'g', 'S')) {

		stream->seek(0);
		return makeVorbisStream(stream, true);

	} else if (tag == 0x3026B275) {

		// ASF (most probably with WMAv2)
		stream->seek(0);
		return makeASFStream(stream, true);

	} else if (((tag & 0xFFFFFF00) | 0x20) == MKTAG('I', 'D', '3', ' ')) {

		// ID3v2 tag found => Should be MP3.
		stream->seek(0);
		isMP3 = true;

	} else if ((tag & 0xFFFA0000) == 0xFFFA0000) {

		// MPEG sync + MPEG1 layer 3 bits found => Should be MP3.
		// NOTE: To decrease the chances of false positives, we could look at more than just the first frame.
		stream->seek(0);
		isMP3 = true;

	} else
		throw Common::Exception("Unknown sound format");

	if (isMP3)
		return makeMP3Stream(stream, true);

	return makeWAVStream(stream, true);
}