From 2249db2c6d7603bf3fc81241fa4b87b0a7f72610 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 28 Jun 2007 17:42:57 +0000 Subject: Started to refactor the Paula / Amiga MOD code: Made some stuff in class Paula private and added accessor APIs instead svn-id: r27759 --- sound/mods/infogrames.cpp | 25 +++++++--------- sound/mods/infogrames.h | 2 +- sound/mods/paula.cpp | 21 +++++++++---- sound/mods/paula.h | 75 +++++++++++++++++++++++++++++++++++------------ sound/mods/protracker.cpp | 25 +++++++--------- sound/mods/rjp1.cpp | 24 +++------------ sound/mods/soundfx.cpp | 38 ++++-------------------- 7 files changed, 103 insertions(+), 107 deletions(-) (limited to 'sound/mods') diff --git a/sound/mods/infogrames.cpp b/sound/mods/infogrames.cpp index b577049657..3f607d213e 100644 --- a/sound/mods/infogrames.cpp +++ b/sound/mods/infogrames.cpp @@ -171,7 +171,7 @@ void Infogrames::init() { _chn[i].periodMod = 0; } - _end = _data == 0; + _end = (_data == 0); } void Infogrames::reset() { @@ -231,8 +231,7 @@ bool Infogrames::load(Common::SeekableReadStream &dum) { (_cmdBlocks > (_data + size))) return false; - _end = false; - _playing = true; + startPaula(); return true; } @@ -244,8 +243,6 @@ void Infogrames::unload(void) { clearVoices(); reset(); - - _end = true; } void Infogrames::getNextSample(Channel &chn) { @@ -427,15 +424,14 @@ void Infogrames::interrupt() { _volume = 0; _period = 0; getNextSample(_chn[chn]); - _voice[chn].volume = _volume; - _voice[chn].period = _period; + setChannelVolume(chn, _volume); + setChannelPeriod(chn, _period); if ((_sample != 0xFF) && (_sample < _instruments->_count)) { - _voice[chn].data = _instruments->_samples[_sample].data; - _voice[chn].length = _instruments->_samples[_sample].length; - _voice[chn].dataRepeat = _instruments->_samples[_sample].dataRepeat; - _voice[chn].lengthRepeat = - _instruments->_samples[_sample].lengthRepeat; - _voice[chn].offset = 0; + setChannelData(chn, + _instruments->_samples[_sample].data, + _instruments->_samples[_sample].dataRepeat, + _instruments->_samples[_sample].length, + _instruments->_samples[_sample].lengthRepeat); _sample = 0xFF; } } @@ -449,8 +445,7 @@ void Infogrames::interrupt() { _repCount--; init(); } else if (_repCount != -1) { - _end = true; - _playing = false; + stopPaula(); } else { init(); } diff --git a/sound/mods/infogrames.h b/sound/mods/infogrames.h index bba43cbef2..572c5a6426 100644 --- a/sound/mods/infogrames.h +++ b/sound/mods/infogrames.h @@ -96,7 +96,7 @@ public: // while data is being read by the mixer thread. _mutex.lock(); init(); - _playing = true; + startPlay(); _mutex.unlock(); } } diff --git a/sound/mods/paula.cpp b/sound/mods/paula.cpp index 53b8f867ea..988ca3f74d 100644 --- a/sound/mods/paula.cpp +++ b/sound/mods/paula.cpp @@ -29,7 +29,6 @@ namespace Audio { Paula::Paula(bool stereo, int rate, int interruptFreq) : _stereo(stereo), _rate(rate), _intFreq(interruptFreq) { - _playing = false; clearVoices(); _voice[0].panning = 63; @@ -41,6 +40,7 @@ Paula::Paula(bool stereo, int rate, int interruptFreq) : _intFreq = _rate; _curInt = _intFreq; + _playing = false; _end = true; } @@ -59,6 +59,15 @@ void Paula::clearVoice(byte voice) { _voice[voice].offset = 0; } +static inline void mix(int16 *&buf, int8 data, byte volume, byte panning, bool stereo) { + const int32 tmp = ((int32) data) * volume; + if (stereo) { + *buf++ += (tmp * (255 - panning)) >> 7; + *buf++ += (tmp * panning) >> 7; + } else + *buf++ += tmp; +} + int Paula::readBuffer(int16 *buffer, const int numSamples) { int voice; int samples; @@ -103,7 +112,7 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) { int end = (int)((sLen - offset) / rate); for (int i = 0; i < end; i++) - mix(p, data[(int)(offset + rate * i)], voice); + mix(p, data[(int)(offset + rate * i)], _voice[voice].volume, _voice[voice].panning, _stereo); _voice[voice].length = sLen = _voice[voice].lengthRepeat; _voice[voice].data = data = _voice[voice].dataRepeat; @@ -118,7 +127,7 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) { end = (int)((sLen - offset) / rate); for (int i = 0; i < end; i++) - mix(p, data[(int)(offset + rate * i)], voice); + mix(p, data[(int)(offset + rate * i)], _voice[voice].volume, _voice[voice].panning, _stereo); _voice[voice].data = data = _voice[voice].dataRepeat; _voice[voice].length = sLen = @@ -128,7 +137,7 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) { neededSamples -= end; } else { for (int i = 0; i < neededSamples; i++) - mix(p, data[(int)(offset + rate * i)], voice); + mix(p, data[(int)(offset + rate * i)], _voice[voice].volume, _voice[voice].panning, _stereo); _voice[voice].offset += rate * neededSamples; if (ceil(_voice[voice].offset) >= sLen) { _voice[voice].data = data = _voice[voice].dataRepeat; @@ -146,14 +155,14 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) { int end = (int)((sLen - offset) / rate); for (int i = 0; i < end; i++) - mix(p, data[(int)(offset + rate * i)], voice); + mix(p, data[(int)(offset + rate * i)], _voice[voice].volume, _voice[voice].panning, _stereo); _voice[voice].offset = sLen; } else { // The requested number of samples is the limiting // factor, not the sample for (int i = 0; i < nSamples; i++) - mix(p, data[(int)(offset + rate * i)], voice); + mix(p, data[(int)(offset + rate * i)], _voice[voice].volume, _voice[voice].panning, _stereo); _voice[voice].offset += rate * nSamples; } } diff --git a/sound/mods/paula.h b/sound/mods/paula.h index 4bf0b8cec2..28fed004a7 100644 --- a/sound/mods/paula.h +++ b/sound/mods/paula.h @@ -45,10 +45,6 @@ public: bool playing() const { return _playing; } void setInterruptFreq(int freq) { _curInt = _intFreq = freq; } - void setPanning(byte voice, byte panning) { - assert(voice < NUM_VOICES); - _voice[voice].panning = panning; - } void clearVoice(byte voice); void clearVoices() { for (int i = 0; i < NUM_VOICES; ++i) clearVoice(i); } void startPlay(void) { _playing = true; } @@ -69,27 +65,68 @@ protected: uint32 lengthRepeat; int16 period; byte volume; - double offset; + double offset; // FIXME: Avoid floating point at all cost!!! byte panning; // For stereo mixing: 0 = far left, 255 = far right - } _voice[NUM_VOICES]; + }; - int _rate; - int _intFreq; - int _curInt; - bool _stereo; bool _end; - bool _playing; Common::Mutex _mutex; - void mix(int16 *&buf, int8 data, int voice) { - const int32 tmp = ((int32) data) * _voice[voice].volume; - if (_stereo) { - *buf++ += (tmp * (255 - _voice[voice].panning)) >> 7; - *buf++ += (tmp * (_voice[voice].panning)) >> 7; - } else - *buf++ += tmp; + virtual void interrupt(void) = 0; + + void startPaula() { + _playing = true; + _end = false; + } + + void stopPaula() { + _playing = false; + _end = true; + } + + void setChannelPanning(byte channel, byte panning) { + assert(channel < NUM_VOICES); + _voice[channel].panning = panning; + } + + void setChannelPeriod(byte channel, int16 period) { + assert(channel < NUM_VOICES); + _voice[channel].period = period; + } + + void setChannelVolume(byte channel, byte volume) { + assert(channel < NUM_VOICES); + _voice[channel].volume = volume; } - virtual void interrupt(void) {} + + void setChannelData(uint8 channel, const int8 *data, const int8 *dataRepeat, uint32 length, uint32 lengthRepeat, double offset = 0.0) { + assert(channel < NUM_VOICES); + Channel &ch = _voice[channel]; + ch.data = data; + ch.dataRepeat = dataRepeat; + ch.length = length; + ch.lengthRepeat = lengthRepeat; + ch.offset = offset; + } + + void setChannelOffset(byte channel, double offset) { + assert(channel < NUM_VOICES); + _voice[channel].offset = offset; + } + + double getChannelOffset(byte channel) { + assert(channel < NUM_VOICES); + return _voice[channel].offset; + } + +private: + Channel _voice[NUM_VOICES]; + + const bool _stereo; + const int _rate; + int _intFreq; + int _curInt; + bool _playing; }; } // End of namespace Audio diff --git a/sound/mods/protracker.cpp b/sound/mods/protracker.cpp index 62a6e1709a..93e252a0f6 100644 --- a/sound/mods/protracker.cpp +++ b/sound/mods/protracker.cpp @@ -37,8 +37,6 @@ class ProtrackerStream : public ::Audio::Paula { private: Module _module; - int _rate; - int _tick; int _row; int _pos; @@ -152,7 +150,6 @@ ProtrackerStream::ProtrackerStream(Common::ReadStream *stream, int rate, bool st bool result = _module.load(*stream); assert(result); - _rate = rate; _tick = _row = _pos = 0; _speed = 6; @@ -172,8 +169,7 @@ ProtrackerStream::ProtrackerStream(Common::ReadStream *stream, int rate, bool st memset(_track, 0, sizeof(_track)); - _playing = true; - _end = false; + startPaula(); } void ProtrackerStream::updateRow() { @@ -249,7 +245,7 @@ void ProtrackerStream::updateRow() { case 0x9: // Set sample offset if (exy) { _track[track].offset = exy * 256; - _voice[track].offset = _track[track].offset; + setChannelOffset(track, _track[track].offset); } break; case 0xA: @@ -409,7 +405,7 @@ void ProtrackerStream::interrupt(void) { int track; for (track = 0; track < 4; track++) - _track[track].offset = _voice[track].offset; + _track[track].offset = getChannelOffset(track); if (_tick == 0) { if (_track[track].arpeggio) { @@ -446,15 +442,16 @@ void ProtrackerStream::interrupt(void) { } for (track = 0; track < 4; track++) { - _voice[track].period = _track[track].period + _track[track].vibrato; - _voice[track].volume = _track[track].vol; + setChannelVolume(track, _track[track].vol); + setChannelPeriod(track, _track[track].period + _track[track].vibrato); if (_track[track].sample) { sample_t &sample = _module.sample[_track[track].sample - 1]; - _voice[track].data = sample.data; - _voice[track].dataRepeat = sample.replen > 2 ? sample.data + sample.repeat : 0; - _voice[track].length = sample.len; - _voice[track].lengthRepeat = sample.replen; - _voice[track].offset = _track[track].offset; + setChannelData(track, + sample.data, + sample.replen > 2 ? sample.data + sample.repeat : 0, + sample.len, + sample.replen, + _track[track].offset); _track[track].sample = 0; } } diff --git a/sound/mods/rjp1.cpp b/sound/mods/rjp1.cpp index ab5d7430be..3f5582de51 100644 --- a/sound/mods/rjp1.cpp +++ b/sound/mods/rjp1.cpp @@ -113,8 +113,6 @@ protected: void stopPaulaChannel(uint8 channel); void setupPaulaChannel(uint8 channel, const int8 *waveData, uint16 offset, uint16 len, uint16 repeatPos, uint16 repeatLen); - void setupPaulaChannelPeriod(uint8 channel, int16 period); - void setPaulaChannelVolume(uint8 channel, uint8 volume); virtual void interrupt(); @@ -202,8 +200,7 @@ void Rjp1::startSong(int song) { } } // "start" Paula audiostream - _playing = true; - _end = false; + startPaula(); } void Rjp1::startSequence(uint8 channelNum, uint8 seqNum) { @@ -351,7 +348,7 @@ void Rjp1::modulatePeriod(Rjp1Channel *channel) { channel->freqInit += channel->freqInc; --channel->freqStep; } - setupPaulaChannelPeriod(channel - _channelsTable, channel->freqInit + channel->modulatePeriodNext); + setChannelPeriod(channel - _channelsTable, channel->freqInit + channel->modulatePeriodNext); } void Rjp1::setupNote(Rjp1Channel *channel, int16 period) { @@ -482,7 +479,7 @@ void Rjp1::modulateVolumeWaveform(Rjp1Channel *channel) { void Rjp1::setVolume(Rjp1Channel *channel) { channel->volume = (channel->volume * channel->volumeScale) / 64; channel->volume = CLIP(channel->volume, 0, 64); - setPaulaChannelVolume(channel - _channelsTable, channel->volume); + setChannelVolume(channel - _channelsTable, channel->volume); } void Rjp1::stopPaulaChannel(uint8 channel) { @@ -491,23 +488,10 @@ void Rjp1::stopPaulaChannel(uint8 channel) { void Rjp1::setupPaulaChannel(uint8 channel, const int8 *waveData, uint16 offset, uint16 len, uint16 repeatPos, uint16 repeatLen) { if (waveData) { - Channel *ch = &_voice[channel]; - ch->data = waveData; - ch->dataRepeat = waveData + repeatPos * 2; - ch->length = len * 2; - ch->lengthRepeat = repeatLen * 2; - ch->offset = offset * 2; + setChannelData(channel, waveData, waveData + repeatPos * 2, len * 2, repeatLen * 2, offset * 2); } } -void Rjp1::setupPaulaChannelPeriod(uint8 channel, int16 period) { - _voice[channel].period = period; -} - -void Rjp1::setPaulaChannelVolume(uint8 channel, uint8 volume) { - _voice[channel].volume = volume; -} - void Rjp1::interrupt() { for (int i = 0; i < 4; ++i) { _vars.currentChannel = i; diff --git a/sound/mods/soundfx.cpp b/sound/mods/soundfx.cpp index c9cb1f007c..b68a664a39 100644 --- a/sound/mods/soundfx.cpp +++ b/sound/mods/soundfx.cpp @@ -63,10 +63,6 @@ protected: void updateEffects(int ch); void handleTick(); - void startPaula(); - void stopPaula(); - void setPaulaChannelPeriod(uint8 channel, int16 period); - void setPaulaChannelVolume(uint8 channel, uint8 volume); void enablePaulaChannel(uint8 channel); void disablePaulaChannel(uint8 channel); void setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen); @@ -174,7 +170,7 @@ void SoundFx::play() { _curOrder = 0; _ticks = 0; _eventsFreq = CIA_FREQ / _delay; - setInterruptFreq(_rate / _eventsFreq); + setInterruptFreq(getRate() / _eventsFreq); startPaula(); } @@ -202,7 +198,7 @@ void SoundFx::handlePattern(int ch, uint32 pat) { } break; } - setPaulaChannelVolume(ch, volume); + setChannelVolume(ch, volume); } } _effects[ch] = note2; @@ -211,7 +207,7 @@ void SoundFx::handlePattern(int ch, uint32 pat) { } else if (note1 == 0xFFFE) { // STP disablePaulaChannel(ch); } else if (note1 != 0) { - setPaulaChannelPeriod(ch, note1); + setChannelPeriod(ch, note1); enablePaulaChannel(ch); } } @@ -256,39 +252,17 @@ void SoundFx::handleTick() { } } -void SoundFx::startPaula() { - _playing = true; - _end = false; -} - -void SoundFx::stopPaula() { - _playing = false; - _end = true; -} - -void SoundFx::setPaulaChannelPeriod(uint8 channel, int16 period) { - _voice[channel].period = period; -} - -void SoundFx::setPaulaChannelVolume(uint8 channel, uint8 volume) { - _voice[channel].volume = volume; -} - void SoundFx::enablePaulaChannel(uint8 channel) { + // FIXME: Is this empty on purpose?!? } void SoundFx::disablePaulaChannel(uint8 channel) { - _voice[channel].period = 0; + setChannelPeriod(channel, 0); } void SoundFx::setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen) { if (data && len > 1) { - Channel *ch = &_voice[channel]; - ch->data = data; - ch->dataRepeat = data + repeatPos * 2; - ch->length = len * 2; - ch->lengthRepeat = repeatLen * 2; - ch->offset = 0; + setChannelData(channel, data, data + repeatPos * 2, len * 2, repeatLen * 2); } } -- cgit v1.2.3