[Scummvm-cvs-logs] CVS: scummvm/sound wave.cpp,NONE,1.1 wave.h,NONE,1.1 module.mk,1.18,1.19 voc.cpp,1.24,1.25

Max Horn fingolfin at users.sourceforge.net
Sun Jan 9 07:50:11 CET 2005


Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv899

Modified Files:
	module.mk voc.cpp 
Added Files:
	wave.cpp wave.h 
Log Message:
Added shared code to load WAV(E) data from arbitrary seekable streams (files or memory)

--- NEW FILE: wave.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-2005 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/sound/wave.cpp,v 1.1 2005/01/09 15:49:43 fingolfin Exp $
 *
 */

#include "stdafx.h"
#include "common/util.h"
#include "common/stream.h"

#include "sound/audiostream.h"
#include "sound/mixer.h"
#include "sound/wave.h"

bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags) {
	const uint32 initialPos = stream.pos();
	byte buf[4+1];

	buf[4] = 0;

	stream.read(buf, 4);
	if (memcmp(buf, "RIFF", 4) != 0) {
		warning("getWavInfo: No 'RIFF' header");
		return false;
	}

	uint32 wavLength = stream.readUint32LE();

	stream.read(buf, 4);
	if (memcmp(buf, "WAVE", 4) != 0) {
		warning("getWavInfo: No 'WAVE' header");
		return false;
	}

	stream.read(buf, 4);
	if (memcmp(buf, "fmt ", 4) != 0) {
		warning("getWavInfo: No 'fmt' header");
		return false;
	}
	
	uint32 fmtLength = stream.readUint32LE();
	if (fmtLength < 16) {
		// A valid fmt chunk always contains at least 16 bytes
		warning("getWavInfo: 'fmt' header is too short");
		return false;
	}

	// Next comes the "type" field of the fmt header. Some typical
	// values for it:
	// 1  -> uncompressed PCM 
	// See <http://www.sonicspot.com/guide/wavefiles.html> for a more complete
	// list of common WAVE compression formats...
	uint16 type = stream.readUint16LE();	// == 1 for PCM data
	uint16 numChannels = stream.readUint16LE();	// 1 for mono, 2 for stereo
	uint32 samplesPerSec = stream.readUint32LE();	// in Hz
	uint32 avgBytesPerSec = stream.readUint32LE();	// == SampleRate * NumChannels * BitsPerSample/8

	uint16 blockAlign = stream.readUint16LE();	// == NumChannels * BitsPerSample/8
	uint16 bitsPerSample = stream.readUint16LE();	// 8, 16 ...
	// 8 bit data is unsigned, 16 bit data signed

#if 0	
	printf("WAVE information:\n");
	printf("  total size: %d\n", wavLength);
	printf("  fmt size: %d\n", fmtLength);
	printf("  type: %d\n", type);
	printf("  numChannels: %d\n", numChannels);
	printf("  samplesPerSec: %d\n", samplesPerSec);
	printf("  avgBytesPerSec: %d\n", avgBytesPerSec);
	printf("  blockAlign: %d\n", blockAlign);
	printf("  bitsPerSample: %d\n", bitsPerSample);
#endif

	if (type != 1) {
		warning("getWavInfo: only PCM data is supported (type %d)", type);
		return false;
	}

	if (blockAlign != numChannels * bitsPerSample / 8) {
		debug(0, "getWavInfo: blockAlign is invalid");
	}

	if (avgBytesPerSec != samplesPerSec * blockAlign) {
		debug(0, "getWavInfo: avgBytesPerSec is invalid");
	}

	// Prepare the return values.
	rate = samplesPerSec;

	flags = 0;
	if (bitsPerSample == 8)		// 8 bit data is unsigned
		flags |= SoundMixer::FLAG_UNSIGNED;
	else if (bitsPerSample == 16)	// 16 bit data is signed
		flags |= SoundMixer::FLAG_16BITS;
	else {
		warning("getWavInfo: unsupported bitsPerSample %d", bitsPerSample);
		return false;
	}
	
	if (numChannels == 2)
		flags |= SoundMixer::FLAG_STEREO;
	else if (numChannels != 1) {
		warning("getWavInfo: unsupported number of channels %d", numChannels);
		return false;
	}

	// It's almost certainly a WAV file, but we still need to find its
	// 'data' chunk.

	// Skip over the rest of the fmt chunk.
	int offset = fmtLength - 16;

	do {
		stream.seek(offset, SEEK_CUR);
		if (stream.pos() >= initialPos + wavLength + 8) {
			warning("getWavInfo: Can't find 'data' chunk");
			return false;
		}
		stream.read(buf, 4);
		offset = stream.readUint32LE();

#if 0
		printf("  found a '%s' tag of size %d\n", buf, offset);
#endif
	} while (memcmp(buf, "data", 4) != 0);
	
	// Stream now points at 'offset' bytes of sample data...
	size = offset;

	return true;
}

AudioStream *makeWAVStream(Common::SeekableReadStream &stream) {
	int size, rate;
	byte flags;
	
	if (!loadWAVFromStream(stream, size, rate, flags))
		return 0;
	
	byte *data = (byte *)malloc(size);
	assert(data);
	stream.read(data, size);
	flags |= SoundMixer::FLAG_AUTOFREE;

	return makeLinearInputStream(rate, flags, data, size, 0, 0);
}

--- NEW FILE: wave.h ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-2005 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/sound/wave.h,v 1.1 2005/01/09 15:49:43 fingolfin Exp $
 *
 */

#ifndef SOUND_WAVE_H
#define SOUND_WAVE_H

#include "stdafx.h"
#include "common/scummsys.h"

class AudioStream;
namespace Common { class SeekableReadStream; }

/**
 * Try to load a WAVE from the given seekable stream. Returns true if successful; in that case,
 * the stream will point at the start of the audio data, and size, rate and flags contain
 * all information about the data necessary for playback.
 * Currently this only support uncompressed raw PCM data.
 */
extern bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate, byte &flags);

AudioStream *makeWAVStream(Common::SeekableReadStream &stream);

#endif

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/module.mk,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- module.mk	25 Dec 2004 18:34:44 -0000	1.18
+++ module.mk	9 Jan 2005 15:49:43 -0000	1.19
@@ -3,6 +3,7 @@
 MODULE_OBJS := \
 	sound/audiocd.o \
 	sound/audiostream.o \
+	sound/flac.o \
 	sound/fmopl.o \
 	sound/mididrv.o \
 	sound/midiparser.o \
@@ -14,7 +15,7 @@
 	sound/rate.o \
 	sound/voc.o \
 	sound/vorbis.o \
-	sound/flac.o \
+	sound/wave.o \
 	sound/softsynth/adlib.o \
 	sound/softsynth/ym2612.o \
 	sound/softsynth/mt32.o \

Index: voc.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/voc.cpp,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- voc.cpp	1 Jan 2005 16:09:23 -0000	1.24
+++ voc.cpp	9 Jan 2005 15:49:43 -0000	1.25
@@ -43,11 +43,6 @@
 	}
 }
 
-byte *loadVOCFromStream(Common::ReadStream &stream, int &size, int &rate) {
-	int loops, begin_loop, end_loop;
-	return loadVOCFromStream(stream, size, rate, loops, begin_loop, end_loop);
-}
-
 byte *loadVOCFromStream(Common::ReadStream &stream, int &size, int &rate, int &loops, int &begin_loop, int &end_loop) {
 	VocFileHeader fileHeader;
 
@@ -128,6 +123,11 @@
 	return ret_sound;
 }
 
+byte *loadVOCFromStream(Common::ReadStream &stream, int &size, int &rate) {
+	int loops, begin_loop, end_loop;
+	return loadVOCFromStream(stream, size, rate, loops, begin_loop, end_loop);
+}
+
 AudioStream *makeVOCStream(Common::ReadStream &stream) {
 	int size, rate;
 	byte *data = loadVOCFromStream(stream, size, rate);





More information about the Scummvm-git-logs mailing list