diff options
| author | Travis Howell | 2006-10-23 01:37:59 +0000 | 
|---|---|---|
| committer | Travis Howell | 2006-10-23 01:37:59 +0000 | 
| commit | 99d6e6db5ce2c0fcb8c3884d7b834ab6728daa66 (patch) | |
| tree | de10147775e39e456d316bfc0f822cdc30bb71d0 | |
| parent | f0a162e8bbfd06340ec63348f5fcfdaca7349bc1 (diff) | |
| download | scummvm-rg350-99d6e6db5ce2c0fcb8c3884d7b834ab6728daa66.tar.gz scummvm-rg350-99d6e6db5ce2c0fcb8c3884d7b834ab6728daa66.tar.bz2 scummvm-rg350-99d6e6db5ce2c0fcb8c3884d7b834ab6728daa66.zip | |
Add patch to make ProTracker a subclass of AudioStream, from madmoose
svn-id: r24465
| -rw-r--r-- | engines/agos/agos.cpp | 8 | ||||
| -rw-r--r-- | engines/agos/agos.h | 2 | ||||
| -rw-r--r-- | engines/agos/res_snd.cpp | 13 | ||||
| -rw-r--r-- | engines/agos/vga.cpp | 2 | ||||
| -rw-r--r-- | sound/mods/module.cpp | 101 | ||||
| -rw-r--r-- | sound/mods/module.h | 11 | ||||
| -rw-r--r-- | sound/mods/protracker.cpp | 375 | ||||
| -rw-r--r-- | sound/mods/protracker.h | 129 | 
8 files changed, 184 insertions, 457 deletions
| diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index d85819ba56..06035cd050 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -399,7 +399,6 @@ AGOSEngine::AGOSEngine(OSystem *syst)  	_vgaTickCounter = 0; -	_modPlayer = 0;  	_moviePlay = 0;  	_sound = 0; @@ -526,12 +525,6 @@ int AGOSEngine::init() {  	_debugger = new Debugger(this);  	_sound = new Sound(this, gss, _mixer); -	if (getPlatform() == Common::kPlatformAmiga) { -		_modPlayer = new Modules::ProtrackerPlayer(); -		_modPlayer->init(_system); -	} else { -		_modPlayer = 0; -	}  	_moviePlay = new MoviePlayer(this, _mixer);  	if (ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute") == 1) { @@ -778,7 +771,6 @@ AGOSEngine::~AGOSEngine() {  	delete [] _windowList;  	delete _debugger; -	delete _modPlayer;  	delete _moviePlay;  	delete _sound;  } diff --git a/engines/agos/agos.h b/engines/agos/agos.h index cc5c695b90..6af12b7def 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -503,7 +503,7 @@ protected:  	int _vgaTickCounter;  	MoviePlayer *_moviePlay; -	Modules::ProtrackerPlayer *_modPlayer; +	Audio::SoundHandle _modHandle;  	Sound *_sound; diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp index 56d88351f0..f7b917b62c 100644 --- a/engines/agos/res_snd.cpp +++ b/engines/agos/res_snd.cpp @@ -30,6 +30,7 @@  #include "agos/agos.h"  #include "agos/vga.h" +#include "sound/audiostream.h"  #include "sound/mididrv.h"  #include "sound/mods/protracker.h" @@ -118,8 +119,7 @@ void AGOSEngine::loadMusic(uint music) {  	if (getPlatform() == Common::kPlatformAtariST) {  		// TODO: Add support for music format used by Elvira 2  	} else if (getPlatform() == Common::kPlatformAmiga) { -		assert(_modPlayer); -		_modPlayer->stop(); +		_mixer->stopHandle(_modHandle);  		char filename[15];  		File f; @@ -134,8 +134,10 @@ void AGOSEngine::loadMusic(uint music) {  			error("loadMusic: Can't load module from '%s'", filename);  		} +		Audio::AudioStream *audioStream;  		if (!(getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO) &&  			getFeatures() & GF_CRUNCHED) { +  			uint srcSize = f.size();  			byte *srcBuf = (byte *)malloc(srcSize);  			if (f.read(srcBuf, srcSize) != srcSize) @@ -147,11 +149,12 @@ void AGOSEngine::loadMusic(uint music) {  			free(srcBuf);  			Common::MemoryReadStream stream(dstBuf, dstSize); -			_modPlayer->loadModuleStream(stream); +			audioStream = Audio::makeProtrackerStream(&stream, _mixer->getOutputRate());  		} else { -			_modPlayer->loadModuleStream(f); +			audioStream = Audio::makeProtrackerStream(&f, _mixer->getOutputRate());  		} -		_modPlayer->start(); + +		_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_modHandle, audioStream);  	} else if (getGameType() == GType_SIMON2) {  		midi.stop();  		_gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET); diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index 04f1903a66..4a2d01014d 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -1439,6 +1439,8 @@ void AGOSEngine::vc57_blackPalette() {  void AGOSEngine::vc58_checkCodeWheel() {  	// TODO  	debug(0, "vc58_checkCodeWheel: stub"); + +	_variableArray[0] = 1;  }  void AGOSEngine::vc59_skipIfNotEGA() { diff --git a/sound/mods/module.cpp b/sound/mods/module.cpp index 4c20c3a741..291f95fe3f 100644 --- a/sound/mods/module.cpp +++ b/sound/mods/module.cpp @@ -22,40 +22,16 @@   */  #include "common/stdafx.h" -#include "common/system.h" -#include "common/file.h" -#include "common/stream.h"  #include "sound/mods/module.h" -namespace Modules { - -bool Module::load(const char *fn) { -	Common::File f; - -	if (!f.open(fn)) -		return false; - -	int bufsz = f.size(); -	byte *buf = new byte[bufsz]; - -	int r = f.read(buf, bufsz); -	assert(r); - -	f.close(); - -	Common::MemoryReadStream st(buf, bufsz); +#include "common/util.h" -	bool result = loadStream(st); - -	delete[] buf; -	 -	return result; -} +namespace Modules { -bool Module::loadStream(Common::SeekableReadStream &st) { +bool Module::load(Common::ReadStream &st) {  	st.read(songname, 20); -	songname[0] = '\0'; +	songname[20] = '\0';  	for (int i = 0; i < 31; ++i) {  		st.read(sample[i].name, 22); @@ -68,18 +44,17 @@ bool Module::loadStream(Common::SeekableReadStream &st) {  		sample[i].vol = st.readByte();  		sample[i].repeat = 2 * st.readUint16BE();  		sample[i].replen = 2 * st.readUint16BE(); - -		//printf("\"%s\"\tlen: %d\tfinetune: %d\tvol: %d\trepeat: %d\treplen: %d\n", -		//       sample[i].name, sample[i].len, sample[i].finetune, sample[i].vol, sample[i].repeat, sample[i].replen); -  	}  	songlen = 2 * st.readByte();  	undef = 2 * st.readByte();  	st.read(songpos, 128); -	st.read(sig, 4);	// Should be "M.K." -	assert(0 == memcmp(sig, "M.K.", 4)); +	st.read(sig, 4); +	if (memcmp(sig, "M.K.", 4)) { +		warning("Expected 'M.K.' in protracker module"); +		return false; +	}  	int maxpattern = 0;  	for (int i = 0; i < 128; ++i) @@ -93,62 +68,9 @@ bool Module::loadStream(Common::SeekableReadStream &st) {  			for (int k = 0; k < 4; ++k) {  				uint32 note = st.readUint32BE();  				pattern[i][j][k].sample = (note & 0xf0000000) >> 24 | (note & 0x0000f000) >> 12; -  				pattern[i][j][k].period = (note >> 16) & 0xfff;  				pattern[i][j][k].effect = note & 0xfff; -/* -        const char *notename; - -        switch (pattern[i][j][k].period) { -          case 856: notename = "C-1"; break; -          case 808: notename = "C#1"; break; -          case 762: notename = "D-1"; break; -          case 720: notename = "D#1"; break; -          case 678: notename = "E-1"; break; -          case 640: notename = "E#1"; break; -          case 604: notename = "F-1"; break; -          case 570: notename = "F#1"; break; -          case 538: notename = "A-1"; break; -          case 508: notename = "A#1"; break; -          case 480: notename = "B-1"; break; -          case 453: notename = "B#1"; break; -          case 428: notename = "C-2"; break; -          case 404: notename = "C#2"; break; -          case 381: notename = "D-2"; break; -          case 360: notename = "D#2"; break; -          case 339: notename = "E-2"; break; -          case 320: notename = "E#2"; break; -          case 302: notename = "F-2"; break; -          case 285: notename = "F#2"; break; -          case 269: notename = "A-2"; break; -          case 254: notename = "A#2"; break; -          case 240: notename = "B-2"; break; -          case 226: notename = "B#2"; break; -          case 214: notename = "C-3"; break; -          case 202: notename = "C#3"; break; -          case 190: notename = "D-3"; break; -          case 180: notename = "D#3"; break; -          case 170: notename = "E-3"; break; -          case 160: notename = "E#3"; break; -          case 151: notename = "F-3"; break; -          case 143: notename = "F#3"; break; -          case 135: notename = "A-3"; break; -          case 127: notename = "A#3"; break; -          case 120: notename = "B-3"; break; -          case 113: notename = "B#3"; break; -          case   0: notename = "   "; break; -          default:  notename = "???"; break; -        } - -        if (k > 0) printf("  |  "); - -        if (pattern[i][j][k].sample) -          printf("%2d %s %3X", pattern[i][j][k].sample, notename, pattern[i][j][k].effect); -        else -          printf("   %s %3X", notename, pattern[i][j][k].effect); -*/  			} -			//printf("\n");  		}  	} @@ -156,12 +78,13 @@ bool Module::loadStream(Common::SeekableReadStream &st) {  		if (!sample[i].len)  			sample[i].data = 0;  		else { -			sample[i].data = new byte[sample[i].len]; +			sample[i].data = new int8[sample[i].len];  			st.read((byte *)sample[i].data, sample[i].len);  		}  	} -	assert(st.eos()); +	if (!st.eos()) +		warning("Expected EOS on module stream");  	return true;  } diff --git a/sound/mods/module.h b/sound/mods/module.h index 4073d5d4ec..1e87b7e1ea 100644 --- a/sound/mods/module.h +++ b/sound/mods/module.h @@ -24,7 +24,7 @@  #ifndef SOUND_MODS_MODULE_H  #define SOUND_MODS_MODULE_H -#include "common/file.h" +#include "common/stream.h"  namespace Modules { @@ -36,12 +36,16 @@ namespace Modules {   * like they are in the file.   */ +#include "common/pack-start.h"	// START STRUCT PACKING +  struct note_t {  	byte sample;  	uint16 period;  	uint16 effect;  }; +#include "common/pack-end.h"	// END STRUCT PACKING +  typedef note_t pattern_t[64][4];  struct sample_t { @@ -51,7 +55,7 @@ struct sample_t {  	byte vol;  	uint16 repeat;  	uint16 replen; -	byte *data; +	int8 *data;  };  class Module { @@ -69,8 +73,7 @@ public:  	Module();  	~Module(); -	bool load(const char *fn); -	bool loadStream(Common::SeekableReadStream &st); +	bool load(Common::ReadStream &stream);  };  } // End of namespace Modules diff --git a/sound/mods/protracker.cpp b/sound/mods/protracker.cpp index 74733d5c15..ab3776624b 100644 --- a/sound/mods/protracker.cpp +++ b/sound/mods/protracker.cpp @@ -22,80 +22,158 @@   */  #include "common/stdafx.h" -#include "common/system.h"  #include "sound/mods/protracker.h" +#include "sound/mods/module.h" + +#include "sound/audiostream.h"  namespace Modules { -#define DUMP 1 +class SoundBuffer { +private: +	int _capacity; +	int _size; +	int16 *_data; + +public: +	SoundBuffer() { +		_size = 0; +		_capacity = 8192; +		_data = (int16 *)malloc(_capacity * sizeof(int16)); +		assert(_data); +	} -void ProtrackerPlayer::init(OSystem *system) { -	_system = system; +	~SoundBuffer() { +		free(_data); +	} -	_buf = new SoundBuffer(); +	int size() { +		return _size; +	} -// FIXME BROKEN: You must NOT use OSystem::setSoundCallback(), -// ever! The only piece of code allowed to use it is the mixer. -// And soon the call might be removed completely, too. -// The proper way to do this is to create a AudioStream -// subclass and hook that with the mixer. See also the -// code used by other softsynths (sound/softsynth/emumidi.h). +	int16 *getEnd() { +		return _data + _size; +	} -//	_system->setSoundCallback(&audioCallback, this); -error("ProtrackerPlayer::init -- setSoundCallback is no more"); -} +	void ensureCapacity(int len) { +		if (_size + len > _capacity) { +			do { +				_capacity *= 2; +			} while (_size + len > _capacity); -void ProtrackerPlayer::start() { -	if (_module) { -		_tick = _row = _pos = 0; -		_hasJumpToPattern = false; -		_hasPatternBreak = false; -		_hasPatternLoop = false; -		_patternLoopCount = 0; -		_patternLoopRow = 0; -		_speed = 6; -		_bpm = 125; - -		_generatedSamplesOverflow = 0.0; - -		for (int t = 0; t < 4; t++) { -			_track[t].sample = 0; -			_track[t].period = 0; -			_track[t].offset = 0.0; - -			_track[t].vibrato = 0; +			_data = (int16 *)realloc(_data, _capacity * sizeof(int16)); +			assert(_data);  		} +	} -		//_system->startAudio(); +	void finish(int len) { +		_size += len;  	} -} -void ProtrackerPlayer::pause() { -} +	void pop(int16 *dest, int len) { +		assert(_size >= len); +		memcpy(dest, _data, len * sizeof(int16)); +		memmove(_data, _data + len, (_size - len) * sizeof(int16)); +		_size -= len; +	} +}; -void ProtrackerPlayer::stop() { -	//_system->stopAudio(); -} +class ProtrackerStream : public ::Audio::AudioStream { +private: +	Module *_module; -void ProtrackerPlayer::loadModule(const char *fn) { -	if (_module) -		delete _module; +	int _rate; +	SoundBuffer *_buf; +	double _generatedSamplesOverflow; -	_module = new Module(); -	_module->load(fn); -} +	int _tick; +	int _row; +	int _pos; + +	int _patternDelay; + +	int _speed; +	int _bpm; + +	// For effect 0xB - Jump To Pattern; +	bool _hasJumpToPattern; +	int _jumpToPattern; + +	// For effect 0xD - PatternBreak; +	bool _hasPatternBreak; +	int _skiprow; + +	// For effect 0xE6 - Pattern Loop +	bool _hasPatternLoop; +	int _patternLoopCount; +	int _patternLoopRow; + +	struct { +		byte sample; +		uint16 period; +		double offset; + +		byte vol; -void ProtrackerPlayer::loadModuleStream(Common::SeekableReadStream &fs) { -	if (_module) -		delete _module; +		// For effect 0x3 - Porta to note +		uint16 portaToNote; +		byte portaToNoteSpeed; +		// For effect 0x4 - Vibrato +		int vibrato; +		byte vibratoPos; +		byte vibratoSpeed; +		byte vibratoDepth; +	} _track[4]; + +public: +	ProtrackerStream(Common::ReadStream *stream, int rate); + +	int readBuffer(int16 *buffer, const int numSamples); +	bool isStereo() const { return false; } +	bool endOfData() const { return false; } + +	int getRate() const { return _rate; } +	 +private: +	void generateSound(); + +	void updateRow(); +	void updateEffects(); +}; + +ProtrackerStream::ProtrackerStream(Common::ReadStream *stream, int rate) {  	_module = new Module(); -	_module->loadStream(fs); +	bool result = _module->load(*stream); +	assert(result); + +	_buf = new SoundBuffer(); +	 +	_rate = rate; +	_tick = _row = _pos = 0; +	_hasJumpToPattern = false; +	_hasPatternBreak = false; +	_hasPatternLoop = false; +	_patternDelay = 0; +	_patternLoopCount = 0; +	_patternLoopRow = 0; +	_speed = 6; +	_bpm = 125; + +	_generatedSamplesOverflow = 0.0; + +	for (int t = 0; t < 4; t++) { +		_track[t].sample = 0; +		_track[t].period = 0; +		_track[t].offset = 0.0; + +		_track[t].vibrato = 0; +	}	  } -void ProtrackerPlayer::generateSound() { -	_generatedSamplesOverflow += 5.0 * 44100.0 / (2.0 * _bpm); +void ProtrackerStream::generateSound() { +	_generatedSamplesOverflow += 5.0 * _rate / (2.0 * _bpm);  	int samples = (int)floor(_generatedSamplesOverflow);  	_generatedSamplesOverflow -= samples; @@ -113,11 +191,11 @@ void ProtrackerPlayer::generateSound() {  			    (7093789.2 / 2.0) / (_track[track].period +  			    _track[track].vibrato); -			double rate = frequency / 44100.0; +			double rate = frequency / _rate;  			double offset = _track[track].offset;  			int sample = _track[track].sample - 1;  			int slen = _module->sample[sample].len; -			byte *data = _module->sample[sample].data; +			int8 *data = _module->sample[sample].data;  			static bool did_warn_about_finetune = false;  			if (!did_warn_about_finetune && _module->sample[sample].finetune != 0) { @@ -128,22 +206,15 @@ void ProtrackerPlayer::generateSound() {  			if (_module->sample[sample].replen > 2) {  				int neededSamples = samples; -				//printf("%d %d >= %d\n", (int)offset, (int)(offset + neededSamples*rate), _module->sample[sample].repeat + _module->sample[sample].replen); -  				while ((int)(offset + neededSamples * rate) >=  				    (_module->sample[sample].repeat + _module->sample[sample].replen)) { -					//puts("/* The repeat length is the limiting factor */"); -					//printf("case 1: period: %d\trate: %g\toffset: %g\tsample: %d\tslen: %d\tvol: %d\n", _track[track].period, rate, _track[track].offset, _track[track].sample, slen, _track[track].vol); +					/* The repeat length is the limiting factor */  					int end =  					    (int)((_module->sample[sample].  						repeat + _module->sample[sample].  						replen - offset) / rate); -					if ((int)(offset + rate * end) > slen) -						warning("!!!!!!!!!"); -					//printf("writing %d-%d max %d\n", (int)offset, (int)(offset + rate*end), slen); -  					for (int i = 0; i < end; i++)  						*p++ +=  						    _track[track].vol * data[(int)(offset + rate * i)]; @@ -153,11 +224,8 @@ void ProtrackerPlayer::generateSound() {  					neededSamples -= end;  				}  				if (neededSamples > 0) { -					//puts("/* The requested number of samples is the limiting factor, not the repeat length */"); -					//printf("case 2: period: %d\trate: %g\toffset: %g\tsample: %d\tslen: %d\tvol: %d\n", _track[track].period, rate, _track[track].offset, _track[track].sample, slen, _track[track].vol); +					/* The requested number of samples is the limiting factor, not the repeat length */ -					//if ((int)(offset + rate*neededSamples) > slen) puts("!!!!!!!!!"); -					//printf("writing %d-%d max %d\n", (int)offset, (int)(offset + rate*neededSamples), slen);  					for (int i = 0; i < neededSamples; i++)  						*p++ +=  						    _track[track].vol * data[(int)(offset + rate * i)]; @@ -169,7 +237,6 @@ void ProtrackerPlayer::generateSound() {  					if ((int)(offset + samples * rate) >=  					    slen) {  						/* The end of the sample is the limiting factor */ -						//printf("case 3: period: %d\trate: %g\toffset: %g\tsample: %d\tslen: %d\tvol: %d\n", _track[track].period, rate, _track[track].offset, _track[track].sample, slen, _track[track].vol);  						int end = (int)((slen - offset) / rate);  						for (int i = 0; i < end; i++) @@ -178,7 +245,6 @@ void ProtrackerPlayer::generateSound() {  						_track[track].offset = slen;  					} else {  						/* The requested number of samples is the limiting factor, not the sample */ -						//printf("case 4: period: %d\trate: %g\toffset: %g\tsample: %d\tslen: %d\tvol: %d\n", _track[track].period, rate, _track[track].offset, _track[track].sample, slen, _track[track].vol);  						for (int i = 0; i < samples; i++)  							*p++ += _track[track].vol * @@ -193,12 +259,7 @@ void ProtrackerPlayer::generateSound() {  	_buf->finish(samples);  } -void ProtrackerPlayer::updateRow() { -	//printf("ProtrackerPlayer::updateRow(): tick: %d\tpos: %d->%d\trow: %d\n", _tick, _pos, _module->songpos[_pos], _row); - -#ifdef DUMP -	printf("%3d:%3d:%2d: ", _pos, _module->songpos[_pos], _row); -#endif +void ProtrackerStream::updateRow() {  	for (int track = 0; track < 4; track++) {  		_track[track].vibrato = 0;  		note_t note = @@ -224,136 +285,6 @@ void ProtrackerPlayer::updateRow() {  		int ex = (note.effect >> 4) & 0xf;  		int ey = note.effect & 0xf; -#ifdef DUMP -		const char *notename; - -		switch (note.period) { -		case 856: -			notename = "C-1"; -			break; -		case 808: -			notename = "C#1"; -			break; -		case 762: -			notename = "D-1"; -			break; -		case 720: -			notename = "D#1"; -			break; -		case 678: -			notename = "E-1"; -			break; -		case 640: -			notename = "E#1"; -			break; -		case 604: -			notename = "F-1"; -			break; -		case 570: -			notename = "F#1"; -			break; -		case 538: -			notename = "A-1"; -			break; -		case 508: -			notename = "A#1"; -			break; -		case 480: -			notename = "B-1"; -			break; -		case 453: -			notename = "B#1"; -			break; -		case 428: -			notename = "C-2"; -			break; -		case 404: -			notename = "C#2"; -			break; -		case 381: -			notename = "D-2"; -			break; -		case 360: -			notename = "D#2"; -			break; -		case 339: -			notename = "E-2"; -			break; -		case 320: -			notename = "E#2"; -			break; -		case 302: -			notename = "F-2"; -			break; -		case 285: -			notename = "F#2"; -			break; -		case 269: -			notename = "A-2"; -			break; -		case 254: -			notename = "A#2"; -			break; -		case 240: -			notename = "B-2"; -			break; -		case 226: -			notename = "B#2"; -			break; -		case 214: -			notename = "C-3"; -			break; -		case 202: -			notename = "C#3"; -			break; -		case 190: -			notename = "D-3"; -			break; -		case 180: -			notename = "D#3"; -			break; -		case 170: -			notename = "E-3"; -			break; -		case 160: -			notename = "E#3"; -			break; -		case 151: -			notename = "F-3"; -			break; -		case 143: -			notename = "F#3"; -			break; -		case 135: -			notename = "A-3"; -			break; -		case 127: -			notename = "A#3"; -			break; -		case 120: -			notename = "B-3"; -			break; -		case 113: -			notename = "B#3"; -			break; -		case 0: -			notename = "   "; -			break; -		default: -			notename = "???"; -			break; -		} - -		if (track > 0) -			printf("  |  "); - -		if (note.sample) -			printf("%2d %s %3X", note.sample, notename, -			    note.effect); -		else -			printf("   %s %3X", notename, note.effect); -#endif -  		switch (effect) {  		case 0x0:  			break; @@ -406,32 +337,24 @@ void ProtrackerPlayer::updateRow() {  			case 0x9:  				break;	// Retrigger note  			default: -				printf("Unimplemented effect %X\n", -				    note.effect); +				warning("Unimplemented effect %X\n", note.effect);  			}  			break;  		case 0xF:  			if (exy < 0x20) {  				_speed = exy; -				//printf("Speed: %x\n", _speed);  			} else {  				_bpm = exy; -				//printf("BPM: %x\n", _bpm);  			}  			break;  		default: -			printf("Unimplemented effect %X\n", note.effect); +			warning("Unimplemented effect %X\n", note.effect);  		}  	} -#ifdef DUMP -	putchar('\n'); -	fflush(NULL); -#endif  } -void ProtrackerPlayer::updateEffects() { -	//printf("ProtrackerPlayer::updateEffects(): tick: %d\tpos: %d->%d\trow: %d\n", _tick, _pos, _module->songpos[_pos], _row); +void ProtrackerStream::updateEffects() {  	static const int16 sinetable[64] = {  		   0,   24,   49,   74,   97,  120,  141,  161, @@ -456,8 +379,6 @@ void ProtrackerPlayer::updateEffects() {  		int ex = (note.effect >> 4) & 0xf;  		int ey = (note.effect) & 0xf; -		//printf("track %d: period: %3d\tsample: %2d\teffect: %x\n", track, note.period, note.sample, note.effect); -  		int vol;  		switch (effect) {  		case 0x0: @@ -568,11 +489,8 @@ void ProtrackerPlayer::updateEffects() {  	}  } -void ProtrackerPlayer::mix(byte *buf0, int len) { -	int16 *buf = (int16 *)buf0; -	len /= 2; - -	while (_buf->size() < len) { +int ProtrackerStream::readBuffer(int16 *buffer, const int numSamples) { +	while (_buf->size() < numSamples) {  		if (_tick == 0) {  			if (_hasJumpToPattern) {  				_hasJumpToPattern = false; @@ -608,12 +526,17 @@ void ProtrackerPlayer::mix(byte *buf0, int len) {  		generateSound();  	} -	_buf->pop(buf, len); -} +	_buf->pop(buffer, numSamples); -void ProtrackerPlayer::audioCallback(void *param, byte *buf, int len) { -	((ProtrackerPlayer *)param)->mix(buf, len); +	return numSamples;  }  } // End of namespace Modules +namespace Audio { + +AudioStream *makeProtrackerStream(Common::ReadStream *stream, int rate) { +	return new Modules::ProtrackerStream(stream, rate); +} + +} // End of namespace Audio diff --git a/sound/mods/protracker.h b/sound/mods/protracker.h index c6511e8a47..d79694d26d 100644 --- a/sound/mods/protracker.h +++ b/sound/mods/protracker.h @@ -25,133 +25,14 @@  #define SOUND_MODS_PROTRACKER_H  #include "common/stdafx.h" -#include "common/system.h" +#include "common/stream.h" -#include "sound/mods/module.h" +namespace Audio { -namespace Modules { +class AudioStream; -class SoundBuffer { -private: -	int _capacity; -	int _size; -	int16 *_data; +AudioStream *makeProtrackerStream(Common::ReadStream *stream, int rate = 44100); -public: -	SoundBuffer() { -		_size = 0; -		_capacity = 8192; -		_data = (int16 *)malloc(_capacity * sizeof(int16)); -		assert(_data); -	} - -	~SoundBuffer() { -		free(_data); -	} - -	int size() { -		return _size; -	} - -	int16 *getEnd() { -		return _data + _size; -	} - -	void ensureCapacity(int len) { -		if (_size + len > _capacity) { -			do { -				_capacity *= 2; -			} while (_size + len > _capacity); - -			_data = (int16 *)realloc(_data, _capacity * sizeof(int16)); -			assert(_data); -			memset(_data + _size, 0, len); -		} -	} - -	void finish(int len) { -		_size += len; -	} - -	void pop(int16 *dest, int len) { -		assert(_size >= len); -		memcpy(dest, _data, len * sizeof(int16)); -		memmove(_data, _data + len, (_size - len) * sizeof(int16)); -		_size -= len; -	} -}; - -class ProtrackerPlayer { -private: -	OSystem *_system; -	Module *_module; - -	SoundBuffer *_buf; -	double _generatedSamplesOverflow; - -	int _tick; -	int _row; -	int _pos; - -	int _patternDelay; - -	int _speed; -	int _bpm; - -	// For effect 0xB - Jump To Pattern; -	bool _hasJumpToPattern; -	int _jumpToPattern; - -	// For effect 0xD - PatternBreak; -	bool _hasPatternBreak; -	int _skiprow; - -	// For effect 0xE6 - Pattern Loop -	bool _hasPatternLoop; -	int _patternLoopCount; -	int _patternLoopRow; - -	struct { -		byte sample; -		uint16 period; -		double offset; - -		byte vol; - -		// For effect 0x3 - Porta to note -		uint16 portaToNote; -		byte portaToNoteSpeed; - -		// For effect 0x4 - Vibrato -		int vibrato; -		byte vibratoPos; -		byte vibratoSpeed; -		byte vibratoDepth; -	} _track[4]; - -public: -	ProtrackerPlayer() : _system(0), _module(0) { }; - -	void init(OSystem *system); - -	void start(); -	void pause(); -	void stop(); - -	void loadModule(const char *fn); -	void loadModuleStream(Common::SeekableReadStream &fs); - -	void mix(byte *buf, int len); - -private: -	void generateSound(); - -	void updateRow(); -	void updateEffects(); - -	static void audioCallback(void *param, byte *buf, int len); -}; - -} // End of namespace Modules +} // End of namespace Audio  #endif | 
