コード例 #1
0
ファイル: wave.cpp プロジェクト: St0rmcrow/scummvm
RewindableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
	int size, rate;
	byte flags;
	uint16 type;
	int blockAlign;

	if (!loadWAVFromStream(*stream, size, rate, flags, &type, &blockAlign)) {
		if (disposeAfterUse == DisposeAfterUse::YES)
			delete stream;
		return 0;
	}

	if (type == 17) // MS IMA ADPCM
		return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMSIma, rate, (flags & Audio::FLAG_STEREO) ? 2 : 1, blockAlign);
	else if (type == 2) // MS ADPCM
		return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMS, rate, (flags & Audio::FLAG_STEREO) ? 2 : 1, blockAlign);

	// Raw PCM. Just read everything at once.
	// TODO: More elegant would be to wrap the stream.
	byte *data = (byte *)malloc(size);
	assert(data);
	stream->read(data, size);

	if (disposeAfterUse == DisposeAfterUse::YES)
		delete stream;

	return makeRawStream(data, size, rate, flags);
}
コード例 #2
0
ファイル: wave.cpp プロジェクト: project-cabal/cabal
RewindableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
	int size, rate;
	byte flags;
	uint16 type;
	int blockAlign;

	if (!loadWAVFromStream(*stream, size, rate, flags, &type, &blockAlign)) {
		if (disposeAfterUse == DisposeAfterUse::YES)
			delete stream;
		return 0;
	}

	if (type == 1) {
		// Raw PCM, make sure the last packet is complete
		uint sampleSize = (flags & Audio::FLAG_16BITS ? 2 : 1) * (flags & Audio::FLAG_STEREO ? 2 : 1);
		if (size % sampleSize != 0) {
			warning("makeWAVStream: Trying to play a WAVE file with an incomplete PCM packet");
			size &= ~(sampleSize - 1);
		}
	}

	Common::SeekableReadStream *substream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + size, disposeAfterUse);

	switch (type) {
	case 1:
		// PCM
		return makePCMStream(substream, rate, flags);
	case 2:
		// MS ADPCM
		return makeADPCMStream(substream, DisposeAfterUse::YES, Audio::kADPCMMS, rate, (flags & Audio::FLAG_STEREO) ? 2 : 1, blockAlign);
	case 17:
		// MS IMA ADPCM
		return makeADPCMStream(substream, DisposeAfterUse::YES, Audio::kADPCMMSIma, rate, (flags & Audio::FLAG_STEREO) ? 2 : 1, blockAlign);
	default:
		// Unknown
		return 0;
	}
}
コード例 #3
0
ファイル: wave.cpp プロジェクト: vincenthamm/scummvm-tools
AudioStream *makeWAVStream(Common::File &stream) {
    int size, rate;
    byte flags;
    uint16 type;
    int blockAlign;

    if (!loadWAVFromStream(stream, size, rate, flags, &type, &blockAlign))
        return 0;

    if (type == 17) // MS IMA ADPCM
        return makeADPCMStream(&stream, size, kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1);
    if (type == 2) // MS ADPCM
        return makeADPCMStream(&stream, size, kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);

    byte *data = (byte *)malloc(size);
    assert(data);
    stream.read_noThrow(data, size);

    // Since we allocated our own buffer for the data, we must set the autofree flag.
    flags |= Audio::Mixer::FLAG_AUTOFREE;

    return makeLinearInputStream(rate, flags, data, size, 0, 0);
}
コード例 #4
0
ファイル: wave.cpp プロジェクト: gitter-badger/xoreos
RewindableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, bool disposeAfterUse) {
	if (stream->readUint32BE() != MKTAG('R', 'I', 'F', 'F'))
		throw Common::Exception("makeWAVStream(): No 'RIFF' header");

	/* uint32 fileSize = */ stream->readUint32LE();

	if (stream->readUint32BE() != MKTAG('W', 'A', 'V', 'E'))
		throw Common::Exception("makeWAVStream(): No 'WAVE' RIFF type");

	if (stream->readUint32BE() != MKTAG('f', 'm', 't', ' '))
		throw Common::Exception("makeWAVStream(): No 'fmt ' chunk");

	uint32 fmtLength = stream->readUint32LE();
	if (fmtLength < 16) // A valid fmt chunk always contains at least 16 bytes
		throw Common::Exception("makeWAVStream(): Invalid wave format size %d", fmtLength);

	// Now parse the WAVEFORMAT(EX) structure
	uint16 compression = stream->readUint16LE();
	uint16 channels = stream->readUint16LE();
	uint32 sampleRate = stream->readUint32LE();
	/* uint32 avgBytesPerSecond = */ stream->readUint32LE();
	uint16 blockAlign = stream->readUint16LE();
	uint16 bitsPerSample = stream->readUint16LE();

	// Skip over the rest of the fmt chunk.
	stream->skip(fmtLength - 16);

	// Skip over all chunks until we hit the data
	for (;;) {
		if (stream->readUint32BE() == MKTAG('d', 'a', 't', 'a'))
			break;

		if (stream->eos())
			throw Common::Exception("makeWAVStream(): Unexpected eos");

		stream->skip(stream->readUint32LE());
	}

	uint32 size = stream->readUint32LE();
	Common::SeekableSubReadStream *subStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + size, disposeAfterUse);

	// Return the decoder we need
	switch (compression) {
	case kWavePCM: {
		byte flags = 0;

		// 8 bit data is unsigned, 16 bit data signed
		if (bitsPerSample == 8)
			flags |= FLAG_UNSIGNED;
		else if (bitsPerSample == 16)
			flags |= (FLAG_16BITS | FLAG_LITTLE_ENDIAN);
		else
			throw Common::Exception("makeWAVStream(): Unsupported PCM bits per sample %d", bitsPerSample);

		return makePCMStream(subStream, sampleRate, flags, channels, true);
	}
	case kWaveMSIMAADPCM:
	case kWaveMSIMAADPCM2:
		return makeADPCMStream(subStream, true, size, kADPCMMSIma, sampleRate, channels, blockAlign);
	case kWaveMSADPCM:
		return makeADPCMStream(subStream, true, size, kADPCMMS, sampleRate, channels, blockAlign);
	}

	throw Common::Exception("makeWAVStream(): Unhandled wave type 0x%04x", compression);
	return 0;
}