aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/mods/infogrames.cpp25
-rw-r--r--sound/mods/infogrames.h2
-rw-r--r--sound/mods/paula.cpp21
-rw-r--r--sound/mods/paula.h75
-rw-r--r--sound/mods/protracker.cpp25
-rw-r--r--sound/mods/rjp1.cpp24
-rw-r--r--sound/mods/soundfx.cpp38
7 files changed, 103 insertions, 107 deletions
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<int16>(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);
}
}