Implement premix proc via an AudioStream / Channel (eventually we'll remove the setupPremix method which takes a proc pointer)

svn-id: r15522
This commit is contained in:
Max Horn 2004-10-11 22:01:21 +00:00
parent 0c785afd2e
commit 1036e88aa6
3 changed files with 82 additions and 45 deletions

View File

@ -302,42 +302,6 @@ void AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::append(const byt
}
}
#pragma mark -
#pragma mark --- Procedural stream ---
#pragma mark -
#if 0
// Work in progress!!! Not yet usable/finished/working/anything :-)
class ProcInputStream : public AudioStream {
public:
typedef void InputProc (void *refCon, int16 *data, uint len);
private:
const int _rate;
const bool _isStereo;
InputProc *_proc;
void *_refCon;
public:
ProcInputStream(int rate, bool stereo, InputProc *proc, void *refCon)
: _rate(rate), _isStereo(stereo), _proc(proc), _refCon(refCon) { }
int readBuffer(int16 *buffer, const int numSamples) {
(_proc)(_refCon, buffer, numSamples);
return numSamples;
}
int16 read() {
int16 sample;
(_proc)(_refCon, &sample, 1);
return sample;
}
bool isStereo() const { return _isStereo; }
bool endOfData() const { return false; }
int getRate() const { return _rate; }
};
#endif
#pragma mark -
#pragma mark --- Input stream factories ---

View File

@ -98,6 +98,43 @@ public:
void finish();
};
#pragma mark -
#pragma mark --- Procedural stream ---
#pragma mark -
class ProcInputStream : public AudioStream {
public:
typedef void (*InputProc)(void *refCon, int16 *data, uint len);
private:
const int _rate;
const bool _isStereo;
InputProc _proc;
void *_refCon;
public:
ProcInputStream(int rate, bool stereo, InputProc proc, void *refCon)
: _rate(rate), _isStereo(stereo), _proc(proc), _refCon(refCon) { }
int readBuffer(int16 *buffer, const int numSamples) {
memset(buffer, 0, 2 * numSamples); // FIXME
(_proc)(_refCon, buffer, _isStereo ? (numSamples / 2) : numSamples);
return numSamples;
}
int16 read() {
error("ProcInputStream::read not supported");
int16 sample[2] = { 0, 0 };
(_proc)(_refCon, sample, 1);
return sample[0];
}
bool isStereo() const { return _isStereo; }
bool endOfData() const { return false; }
int getRate() const { return _rate; }
};
#pragma mark -
#pragma mark --- SoundMixer ---
#pragma mark -
@ -107,8 +144,7 @@ SoundMixer::SoundMixer() {
_syst = OSystem::instance();
_mutex = _syst->createMutex();
_premixParam = 0;
_premixProc = 0;
_premixChannel = 0;
int i = 0;
_globalVolume = 0;
@ -131,6 +167,10 @@ SoundMixer::SoundMixer() {
SoundMixer::~SoundMixer() {
_syst->clearSoundCallback();
stopAll();
delete _premixChannel;
_premixChannel = 0;
_syst->deleteMutex(_mutex);
}
@ -140,8 +180,31 @@ bool SoundMixer::isPaused() {
void SoundMixer::setupPremix(PremixProc *proc, void *param) {
Common::StackLock lock(_mutex);
_premixParam = param;
_premixProc = proc;
delete _premixChannel;
_premixChannel = 0;
if (proc == 0)
return;
// Create an input stream
AudioStream *input = new ProcInputStream(_outputRate, true, proc, param);
// Create the channel
_premixChannel = new Channel(this, 0, input, true, false);
}
void SoundMixer::setupPremix(AudioStream *stream) {
Common::StackLock lock(_mutex);
delete _premixChannel;
_premixChannel = 0;
if (stream == 0)
return;
// Create the channel
_premixChannel = new Channel(this, 0, stream, false, false);
}
void SoundMixer::newStream(PlayingSoundHandle *handle, uint rate, byte flags, uint32 buffer_size, byte volume, int8 balance) {
@ -315,8 +378,8 @@ void SoundMixer::mix(int16 *buf, uint len) {
memset(buf, 0, 2 * len * sizeof(int16));
if (!_paused) {
if (_premixProc)
_premixProc(_premixParam, buf, len);
if (_premixChannel)
_premixChannel->mix(buf, len);
// now mix all channels
for (int i = 0; i != NUM_CHANNELS; i++)

View File

@ -66,8 +66,7 @@ private:
OSystem *_syst;
OSystem::MutexRef _mutex;
void *_premixParam;
PremixProc *_premixProc;
Channel *_premixChannel;
uint _outputRate;
@ -96,13 +95,24 @@ public:
* Set the premix procedure. This is mainly used for the adlib music, but
* is not limited to it. The premix proc is invoked by the mixer whenever
* it needs to generate any data, before any other mixing takes place. The
* premixer than has a chanve to fill the mix buffer with data (usually
* premixer than has a chance to fill the mix buffer with data (usually
* music samples). It should generate the specified number of 16bit stereo
* samples (i.e. len * 4 bytes). The endianness of these samples shall be
* the native endianness.
*
* @obsolete Instead of this, use the other setupPremix method which
* takes an AudioStream.
*/
void setupPremix(PremixProc *proc, void *param);
/**
* Set the premix stream. This is mainly used for the adlib music, but
* is not limited to it. The premix stream is invoked by the mixer whenever
* it needs to generate any data, before any other mixing takes place.
*/
void setupPremix(AudioStream *stream);
// start playing a raw sound
void playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags,
int id = -1, byte volume = 255, int8 balance = 0, uint32 loopStart = 0, uint32 loopEnd = 0);