[Scummvm-cvs-logs] SF.net SVN: scummvm: [29564] scummvm/trunk

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Mon Nov 19 00:35:10 CET 2007


Revision: 29564
          http://scummvm.svn.sourceforge.net/scummvm/?rev=29564&view=rev
Author:   drmccoy
Date:     2007-11-18 15:35:09 -0800 (Sun, 18 Nov 2007)

Log Message:
-----------
Moved Gob's square wave generator to sound/softsynth/pcspk.h

Modified Paths:
--------------
    scummvm/trunk/engines/gob/sound.cpp
    scummvm/trunk/engines/gob/sound.h
    scummvm/trunk/sound/module.mk

Added Paths:
-----------
    scummvm/trunk/sound/softsynth/pcspk.cpp
    scummvm/trunk/sound/softsynth/pcspk.h

Modified: scummvm/trunk/engines/gob/sound.cpp
===================================================================
--- scummvm/trunk/engines/gob/sound.cpp	2007-11-18 22:22:38 UTC (rev 29563)
+++ scummvm/trunk/engines/gob/sound.cpp	2007-11-18 23:35:09 UTC (rev 29564)
@@ -93,73 +93,6 @@
 	_size = dSize;
 }
 
-Snd::SquareWaveStream::SquareWaveStream() {
-	_rate = 44100;
-	_beepForever = false;
-	_periodLength = 0;
-	_periodSamples = 0;
-	_remainingSamples = 0;
-	_sampleValue = 0;
-	_mixedSamples = 0;
-}
-
-void Snd::SquareWaveStream::playNote(int freq, int32 ms, uint rate) {
-	_rate = rate;
-	_periodLength = _rate / (2 * freq);
-	_periodSamples = 0;
-	_sampleValue = 6000;
-	if (ms == -1) {
-		_remainingSamples = 1;
-		_beepForever = true;
-	} else {
-		_remainingSamples = (_rate * ms) / 1000;
-		_beepForever = false;
-	}
-	_mixedSamples = 0;
-}
-
-void Snd::SquareWaveStream::stop(uint32 milis) {
-	if (!_beepForever)
-		return;
-
-	if (milis)
-		update(milis);
-	else
-		_remainingSamples = 0;
-}
-
-void Snd::SquareWaveStream::update(uint32 milis) {
-	uint32 neededSamples;
-
-	if (!_beepForever || !_remainingSamples)
-		return;
-
-	neededSamples = (_rate * milis) / 1000;
-	_remainingSamples =
-		neededSamples > _mixedSamples ? neededSamples - _mixedSamples : 0;
-	_beepForever = false;
-}
-
-int Snd::SquareWaveStream::readBuffer(int16 *buffer, const int numSamples) {
-	int i;
-	for (i = 0; _remainingSamples && i < numSamples; i++) {
-		buffer[i] = _sampleValue;
-		if (_periodSamples++ > _periodLength) {
-			_periodSamples = 0;
-			_sampleValue = -_sampleValue;
-		}
-		if (!_beepForever)
-			_remainingSamples--;
-		_mixedSamples++;
-	}
-
-	// Clear the rest of the buffer
-	if (i < numSamples)
-		memset(buffer + i, 0, (numSamples - i) * sizeof(int16));
-
-	return numSamples;
-}
-
 Snd::Snd(GobEngine *vm) : _vm(vm) {
 	_playingSound = 0;
 	_curSoundDesc = 0;
@@ -188,10 +121,12 @@
 	_compositionSampleCount = 0;
 	_compositionPos = -1;
 
+	_speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
+
 	_vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle,
 			this, -1, 255, 0, false, true);
 	_vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
-			&_speakerStream, -1, 255, 0, false, true);
+			_speakerStream, -1, 50, 0, false, true);
 }
 
 Snd::~Snd() {
@@ -199,22 +134,22 @@
 
 	// First the speaker stream
 	_vm->_mixer->stopHandle(_speakerHandle);
+	delete _speakerStream;
 
 	// Next, this stream (class Snd is an AudioStream, too)
 	_vm->_mixer->stopHandle(_handle);
 }
 
 void Snd::speakerOn(int16 frequency, int32 length) {
-	_speakerStream.playNote(frequency, length, _vm->_mixer->getOutputRate());
-	_speakerStartTimeKey = _vm->_util->getTimeKey();
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length);
 }
 
 void Snd::speakerOff() {
-	_speakerStream.stop(_vm->_util->getTimeKey() - _speakerStartTimeKey);
+	_speakerStream->stop();
 }
 
 void Snd::speakerOnUpdate(uint32 milis) {
-	_speakerStream.update(milis);
+	_speakerStream->stop(milis);
 }
 
 void Snd::stopSound(int16 fadeLength, SoundDesc *sndDesc) {

Modified: scummvm/trunk/engines/gob/sound.h
===================================================================
--- scummvm/trunk/engines/gob/sound.h	2007-11-18 22:22:38 UTC (rev 29563)
+++ scummvm/trunk/engines/gob/sound.h	2007-11-18 23:35:09 UTC (rev 29564)
@@ -30,6 +30,7 @@
 #include "common/frac.h"
 #include "sound/audiostream.h"
 #include "sound/mixer.h"
+#include "sound/softsynth/pcspk.h"
 
 namespace Gob {
 
@@ -123,39 +124,8 @@
 	int getRate() const { return _rate; }
 
 protected:
-	// TODO: This is a very primitive square wave generator. The only thing it
-	//       has in common with the PC speaker is that it sounds terrible.
-	// Note: The SCUMM code has a PC speaker implementations; maybe it could be
-	//       refactored to be reusable by all engines. And DosBox also has code
-	//       for emulating the PC speaker.
-	class SquareWaveStream : public Audio::AudioStream {
-	private:
-		uint _rate;
-		bool _beepForever;
-		uint32 _periodLength;
-		uint32 _periodSamples;
-		uint32 _remainingSamples;
-		uint32 _mixedSamples;
-		int16 _sampleValue;
-
-	public:
-		SquareWaveStream();
-
-		void playNote(int freq, int32 ms, uint rate);
-		void update(uint32 milis);
-		void stop(uint32 milis);
-
-		int readBuffer(int16 *buffer, const int numSamples);
-
-		bool isStereo() const	{ return false; }
-		bool endOfData() const	{ return false; }
-		bool endOfStream() const { return false; }
-		int getRate() const	{ return _rate; }
-	};
-
-	SquareWaveStream _speakerStream;
+	Audio::PCSpeaker *_speakerStream;
 	Audio::SoundHandle _speakerHandle;
-	uint32 _speakerStartTimeKey;
 
 	Audio::SoundHandle *_activeHandle;
 	Audio::SoundHandle _compositionHandle;

Modified: scummvm/trunk/sound/module.mk
===================================================================
--- scummvm/trunk/sound/module.mk	2007-11-18 22:22:38 UTC (rev 29563)
+++ scummvm/trunk/sound/module.mk	2007-11-18 23:35:09 UTC (rev 29564)
@@ -29,6 +29,7 @@
 	softsynth/ym2612.o \
 	softsynth/fluidsynth.o \
 	softsynth/mt32.o \
+	softsynth/pcspk.o
 
 ifndef USE_ARM_SOUND_ASM
 MODULE_OBJS += \

Added: scummvm/trunk/sound/softsynth/pcspk.cpp
===================================================================
--- scummvm/trunk/sound/softsynth/pcspk.cpp	                        (rev 0)
+++ scummvm/trunk/sound/softsynth/pcspk.cpp	2007-11-18 23:35:09 UTC (rev 29564)
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* $URL$
+* $Id$
+*
+*/
+
+#include "sound/softsynth/pcspk.h"
+
+namespace Audio {
+
+const PCSpeaker::generatorFunc PCSpeaker::generateWave[] =
+	{&PCSpeaker::generateSquare, &PCSpeaker::generateSine,
+	 &PCSpeaker::generateSaw,    &PCSpeaker::generateTriangle};
+
+PCSpeaker::PCSpeaker(int rate) {
+	_rate = rate;
+	_wave = kWaveFormSquare;
+	_playForever = false;
+	_oscLength = 0;
+	_oscSamples = 0;
+	_remainingSamples = 0;
+	_mixedSamples = 0;
+	_volume = 255;
+}
+
+PCSpeaker::~PCSpeaker() {
+}
+
+void PCSpeaker::play(WaveForm wave, int freq, int32 length) {
+	Common::StackLock lock(_mutex);
+
+	assert((wave >= kWaveFormSquare) && (wave <= kWaveFormTriangle));
+
+	_wave = wave;
+	_oscLength = _rate / freq;
+	_oscSamples = 0;
+	if (length == -1) {
+		_remainingSamples = 1;
+		_playForever = true;
+	} else {
+		_remainingSamples = (_rate * length) / 1000;
+		_playForever = false;
+	}
+	_mixedSamples = 0;
+}
+
+void PCSpeaker::stop(int32 delay) {
+	Common::StackLock lock(_mutex);
+
+	_remainingSamples = (_rate * delay) / 1000;
+	_playForever = false;
+}
+
+void PCSpeaker::setVolume(byte volume) {
+	_volume = volume;
+}
+
+int PCSpeaker::readBuffer(int16 *buffer, const int numSamples) {
+	Common::StackLock lock(_mutex);
+
+	int i;
+
+	for (i = 0; _remainingSamples && (i < numSamples); i++) {
+		buffer[i] = generateWave[_wave](_oscSamples, _oscLength) * _volume;
+		if (_oscSamples++ >= _oscLength)
+			_oscSamples = 0;
+		if (!_playForever)
+			_remainingSamples--;
+		_mixedSamples++;
+	}
+
+	// Clear the rest of the buffer
+	if (i < numSamples)
+		memset(buffer + i, 0, (numSamples - i) * sizeof(int16));
+
+	return numSamples;
+}
+
+int8 PCSpeaker::generateSquare(uint32 x, uint32 oscLength) {
+	return (x < (oscLength / 2)) ? 127 : -128;
+}
+
+int8 PCSpeaker::generateSine(uint32 x, uint32 oscLength) {
+	if (oscLength == 0)
+		return 0;
+
+	// TODO: Maybe using a look-up-table would be better?
+	return CLIP<int16>((int16) (128 * sin(2.0 * M_PI * x / oscLength)), -128, 127);
+}
+
+int8 PCSpeaker::generateSaw(uint32 x, uint32 oscLength) {
+	if (oscLength == 0)
+		return 0;
+
+	return ((x * (65536 / oscLength)) >> 8) - 128;
+}
+
+int8 PCSpeaker::generateTriangle(uint32 x, uint32 oscLength) {
+	if (oscLength == 0)
+		return 0;
+
+	int y = ((x * (65536 / (oscLength / 2))) >> 8) - 128;
+
+	return (x <= (oscLength / 2)) ? y : (256 - y);
+}
+
+} // End of namespace Audio


Property changes on: scummvm/trunk/sound/softsynth/pcspk.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/sound/softsynth/pcspk.h
===================================================================
--- scummvm/trunk/sound/softsynth/pcspk.h	                        (rev 0)
+++ scummvm/trunk/sound/softsynth/pcspk.h	2007-11-18 23:35:09 UTC (rev 29564)
@@ -0,0 +1,86 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef SOUND_SOFTSYNTH_PCSPK_H
+#define SOUND_SOFTSYNTH_PCSPK_H
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "common/mutex.h"
+
+namespace Audio {
+
+class PCSpeaker : public AudioStream {
+public:
+	enum WaveForm {
+		kWaveFormSquare = 0,
+		kWaveFormSine,
+		kWaveFormSaw,
+		kWaveFormTriangle
+	};
+
+	PCSpeaker(int rate = 44100);
+	~PCSpeaker();
+
+	/** Play a note for length ms.
+	 *
+	 *  If length is negative, play until told to stop.
+	 */
+	void play(WaveForm wave, int freq, int32 length);
+	/** Stop the currently playing note after delay ms. */
+	void stop(int32 delay = 0);
+	/** Adjust the volume. */
+	void setVolume(byte volume);
+
+	int readBuffer(int16 *buffer, const int numSamples);
+
+	bool isStereo() const	{ return false; }
+	bool endOfData() const	{ return false; }
+	bool endOfStream() const { return false; }
+	int getRate() const	{ return _rate; }
+
+protected:
+	Common::Mutex _mutex;
+
+	int _rate;
+	WaveForm _wave;
+	bool _playForever;
+	uint32 _oscLength;
+	uint32 _oscSamples;
+	uint32 _remainingSamples;
+	uint32 _mixedSamples;
+	byte _volume;
+
+	typedef int8 (*generatorFunc)(uint32, uint32);
+	static const generatorFunc generateWave[];
+
+	static int8 generateSquare(uint32 x, uint32 oscLength);
+	static int8 generateSine(uint32 x, uint32 oscLength);
+	static int8 generateSaw(uint32 x, uint32 oscLength);
+	static int8 generateTriangle(uint32 x, uint32 oscLength);
+};
+
+} // End of namespace Audio
+
+#endif // SOUND_SOFTSYNTH_PCSPEAKER_H


Property changes on: scummvm/trunk/sound/softsynth/pcspk.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list