diff options
author | Max Horn | 2004-12-25 18:34:44 +0000 |
---|---|---|
committer | Max Horn | 2004-12-25 18:34:44 +0000 |
commit | fec3df209601b812034fafed53ef74b7ee732512 (patch) | |
tree | 14572de096e66b3720faf67dbd9d3cf3f3926422 /sound/softsynth/emumidi.h | |
parent | 0d2fa6ecf02d5745db90d78c78e546b3fe62d373 (diff) | |
download | scummvm-rg350-fec3df209601b812034fafed53ef74b7ee732512.tar.gz scummvm-rg350-fec3df209601b812034fafed53ef74b7ee732512.tar.bz2 scummvm-rg350-fec3df209601b812034fafed53ef74b7ee732512.zip |
Moved the softsynth midi drivers into a sound/softsynth; amongst other things, this fixes bug #1083058
svn-id: r16316
Diffstat (limited to 'sound/softsynth/emumidi.h')
-rw-r--r-- | sound/softsynth/emumidi.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/sound/softsynth/emumidi.h b/sound/softsynth/emumidi.h new file mode 100644 index 0000000000..34cd4b0983 --- /dev/null +++ b/sound/softsynth/emumidi.h @@ -0,0 +1,107 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2004 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$ + */ + +#include "stdafx.h" +#include "sound/audiostream.h" +#include "sound/mididrv.h" +#include "sound/mixer.h" + +#define FIXP_SHIFT 16 + +class MidiDriver_Emulated : public AudioStream, public MidiDriver { +protected: + bool _isOpen; + SoundMixer *_mixer; + +private: + Timer::TimerProc _timerProc; + void *_timerParam; + + int _nextTick; + int _samplesPerTick; + +protected: + virtual void generateSamples(int16 *buf, int len) = 0; + virtual void onTimer() {} + + int _baseFreq; + +public: + MidiDriver_Emulated(SoundMixer *mixer) : _mixer(mixer) { + _isOpen = false; + + _timerProc = 0; + _timerParam = 0; + + _nextTick = 0; + _samplesPerTick = 0; + + _baseFreq = 250; + } + + int open() { + _isOpen = true; + + int d = getRate() / _baseFreq; + int r = getRate() % _baseFreq; + + // This is equivalent to (getRate() << FIXP_SHIFT) / BASE_FREQ + // but less prone to arithmetic overflow. + + _samplesPerTick = (d << FIXP_SHIFT) + (r << FIXP_SHIFT) / _baseFreq; + return 0; + } + + void setTimerCallback(void *timer_param, Timer::TimerProc timer_proc) { + _timerProc = timer_proc; + _timerParam = timer_param; + } + + uint32 getBaseTempo() { return 1000000 / _baseFreq; } + + + // AudioStream API + int readBuffer(int16 *data, const int numSamples) { + const int stereoFactor = isStereo() ? 2 : 1; + int len = numSamples / stereoFactor; + int step; + + do { + step = len; + if (step > (_nextTick >> FIXP_SHIFT)) + step = (_nextTick >> FIXP_SHIFT); + + generateSamples(data, step); + + _nextTick -= step << FIXP_SHIFT; + if (!(_nextTick >> FIXP_SHIFT)) { + if (_timerProc) + (*_timerProc)(_timerParam); + onTimer(); + _nextTick += _samplesPerTick; + } + data += step * stereoFactor; + len -= step; + } while (len); + + return numSamples; + } + bool endOfData() const { return false; } +}; |