aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/music.cpp
diff options
context:
space:
mode:
authorSven Hesse2007-01-25 14:18:12 +0000
committerSven Hesse2007-01-25 14:18:12 +0000
commit604077827f44d027e7c3afd3200afe1a901e1c2a (patch)
tree36049c29fb3533a4725d1e4c1189f16b8c63503e /engines/gob/music.cpp
parent30b7ac3db529c80d71d89ee41a09bce3d9076309 (diff)
downloadscummvm-rg350-604077827f44d027e7c3afd3200afe1a901e1c2a.tar.gz
scummvm-rg350-604077827f44d027e7c3afd3200afe1a901e1c2a.tar.bz2
scummvm-rg350-604077827f44d027e7c3afd3200afe1a901e1c2a.zip
- Some clean-up
- Fixed sound playing and looping - Changed Paula to use non-absolute panning, defaulting to 0.25/0.75 and 0.75/0.25, as per madmoose's suggestion - Prepared/Cleaned-up Paula and Infogrames for the move to sound/mods/ svn-id: r25189
Diffstat (limited to 'engines/gob/music.cpp')
-rw-r--r--engines/gob/music.cpp212
1 files changed, 102 insertions, 110 deletions
diff --git a/engines/gob/music.cpp b/engines/gob/music.cpp
index 0411f82761..7c18d57a23 100644
--- a/engines/gob/music.cpp
+++ b/engines/gob/music.cpp
@@ -32,19 +32,15 @@
namespace Gob {
-Paula::Paula(GobEngine *vm, bool stereo, int intFreq) : _vm(vm) {
+Paula::Paula(bool stereo, int rate, int interruptFreq) :
+ _stereo(stereo), _rate(rate), _intFreq(interruptFreq) {
_playing = false;
- _stereo = stereo;
- _rate = _vm->_mixer->getOutputRate();
- _vm->_mixer->setupPremix(this, Audio::Mixer::kMusicSoundType);
- _intFreq = intFreq;
-
clearVoices();
- _voice[0].panning = 0;
- _voice[1].panning = 1;
- _voice[2].panning = 1;
- _voice[3].panning = 0;
+ _voice[0].panning = 63;
+ _voice[1].panning = 191;
+ _voice[2].panning = 191;
+ _voice[3].panning = 63;
if (_intFreq <= 0)
_intFreq = _rate;
@@ -54,10 +50,12 @@ Paula::Paula(GobEngine *vm, bool stereo, int intFreq) : _vm(vm) {
}
Paula::~Paula() {
- _vm->_mixer->setupPremix(0);
}
-void Paula::clearVoice(int voice) {
+void Paula::clearVoice(byte voice) {
+ if (voice >= 4)
+ return;
+
_voice[voice].data = 0;
_voice[voice].dataRepeat = 0;
_voice[voice].length = 0;
@@ -78,9 +76,14 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) {
int16 *p;
int8 *data;
+ _mutex.lock();
+
memset(buffer, 0, numSamples * 2);
if (!_playing)
+ {
+ _mutex.unlock();
return numSamples;
+ }
samples = _stereo ? numSamples / 2 : numSamples;
while (samples > 0) {
@@ -101,7 +104,8 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) {
p = buffer;
_voice[voice].volume &= 0x3F;
- if ((_voice[voice].lengthRepeat > 2) && ((int)(offset + nSamples * rate) >= sLen)) {
+ if ((_voice[voice].lengthRepeat > 2) &&
+ ((int)(offset + nSamples * rate) >= sLen)) {
int neededSamples = nSamples;
int end = (int)((sLen - offset) / rate);
@@ -122,7 +126,8 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) {
mix(p, data[(int)(offset + rate * i)], voice);
_voice[voice].data = data = _voice[voice].dataRepeat;
- _voice[voice].length = sLen = _voice[voice].lengthRepeat;
+ _voice[voice].length = sLen =
+ _voice[voice].lengthRepeat;
_voice[voice].offset = offset = 0;
neededSamples -= end;
@@ -132,7 +137,8 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) {
_voice[voice].offset += rate * neededSamples;
if (ceil(_voice[voice].offset) >= sLen) {
_voice[voice].data = data = _voice[voice].dataRepeat;
- _voice[voice].length = sLen = _voice[voice].lengthRepeat;
+ _voice[voice].length = sLen =
+ _voice[voice].lengthRepeat;
_voice[voice].offset = offset = 0;
}
neededSamples = 0;
@@ -148,7 +154,8 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) {
mix(p, data[(int)(offset + rate * i)], voice);
_voice[voice].offset = sLen;
} else {
- // The requested number of samples is the limiting factor, not the sample
+ // 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);
@@ -161,10 +168,20 @@ int Paula::readBuffer(int16 *buffer, const int numSamples) {
_curInt += nSamples;
samples -= nSamples;
}
+ _mutex.unlock();
return numSamples;
}
Infogrames::Instruments::Instruments() {
+ init();
+}
+
+Infogrames::Instruments::~Instruments() {
+ if (_sampleData)
+ delete[] _sampleData;
+}
+
+void Infogrames::Instruments::init() {
int i;
for (i = 0; i < 32; i++) {
@@ -177,11 +194,6 @@ Infogrames::Instruments::Instruments() {
_sampleData = 0;
}
-Infogrames::Instruments::~Instruments() {
- if (_sampleData)
- delete[] _sampleData;
-}
-
bool Infogrames::Instruments::load(Common::SeekableReadStream &ins) {
int i;
uint32 fsize;
@@ -189,13 +201,16 @@ bool Infogrames::Instruments::load(Common::SeekableReadStream &ins) {
uint32 offsetRepeat[32];
uint32 dataOffset;
+ unload();
+
fsize = ins.readUint32BE();
dataOffset = fsize;
for (i = 0; (i < 32) && !ins.eos(); i++) {
offset[i] = ins.readUint32BE();
offsetRepeat[i] = ins.readUint32BE();
if ((offset[i] > fsize) || (offsetRepeat[i] > fsize) ||
- (offset[i] < (ins.pos() + 4)) || (offsetRepeat[i] < (ins.pos() + 4))) {
+ (offset[i] < (ins.pos() + 4)) ||
+ (offsetRepeat[i] < (ins.pos() + 4))) {
// Definitely no real entry anymore
ins.seek(-8, SEEK_CUR);
break;
@@ -223,29 +238,38 @@ bool Infogrames::Instruments::load(Common::SeekableReadStream &ins) {
return true;
}
+void Infogrames::Instruments::unload(void) {
+ if (_sampleData)
+ delete[] _sampleData;
+ init();
+}
+
+const uint8 Infogrames::tickCount[] =
+ {2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96};
const uint16 Infogrames::periods[] =
{0x6ACC, 0x64CC, 0x5F25, 0x59CE, 0x54C3, 0x5003, 0x4B86, 0x4747, 0x4346,
- 0x3F8B, 0x3BF3, 0x3892, 0x3568, 0x3269, 0x2F93, 0x2CEA, 0x2A66, 0x2801,
- 0x2566, 0x23A5, 0x21AF, 0x1FC4, 0x1DFE, 0x1C4E, 0x1ABC, 0x1936, 0x17CC,
- 0x1676, 0x1533, 0x1401, 0x12E4, 0x11D5, 0x10D4, 0xFE3, 0xEFE, 0xE26,
- 0xD5B, 0xC9B, 0xBE5, 0xB3B, 0xA9B, 0xA02, 0x972, 0x8E9, 0x869, 0x7F1,
- 0x77F, 0x713, 0x6AD, 0x64D, 0x5F2, 0x59D, 0x54D, 0x500, 0x4B8, 0x475,
- 0x435, 0x3F8, 0x3BF, 0x38A, 0x356, 0x326, 0x2F9, 0x2CF, 0x2A6, 0x280,
- 0x25C, 0x23A, 0x21A, 0x1FC, 0x1E0, 0x1C5, 0x1AB, 0x193, 0x17D, 0x167,
- 0x153, 0x140, 0x12E, 0x11D, 0x10D, 0xFE, 0xF0, 0xE2, 0xD6, 0xCA, 0xBE,
- 0xB4, 0xAA, 0xA0, 0x97, 0x8F, 0x87, 0x7F, 0x78, 0x70, 0x60, 0x50, 0x40,
- 0x30, 0x20, 0x10, 0, 0, 0x20, 0x2020, 0x2020, 0x2020, 0x2020, 0x3030,
- 0x3030, 0x3020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
- 0x2020, 0x2090, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040,
- 0x400C, 0xC0C, 0xC0C, 0xC0C, 0xC0C, 0xC40, 0x4040, 0x4040, 0x4040, 0x909,
- 0x909, 0x909, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101,
- 0x101, 0x4040, 0x4040, 0x4040, 0xA0A, 0xA0A, 0xA0A, 0x202, 0x202, 0x202,
- 0x202, 0x202, 0x202, 0x202, 0x202, 0x202, 0x202, 0x4040, 0x4040, 0x2000};
-const uint8 Infogrames::tickCount[] = {2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96};
-
-Infogrames::Infogrames(GobEngine *vm, bool stereo) :
- Paula(vm, stereo, vm->_mixer->getOutputRate()/80) {
- _instruments = 0;
+ 0x3F8B, 0x3BF3, 0x3892, 0x3568, 0x3269, 0x2F93, 0x2CEA, 0x2A66, 0x2801,
+ 0x2566, 0x23A5, 0x21AF, 0x1FC4, 0x1DFE, 0x1C4E, 0x1ABC, 0x1936, 0x17CC,
+ 0x1676, 0x1533, 0x1401, 0x12E4, 0x11D5, 0x10D4, 0x0FE3, 0x0EFE, 0x0E26,
+ 0x0D5B, 0x0C9B, 0x0BE5, 0x0B3B, 0x0A9B, 0x0A02, 0x0972, 0x08E9, 0x0869,
+ 0x07F1, 0x077F, 0x0713, 0x06AD, 0x064D, 0x05F2, 0x059D, 0x054D, 0x0500,
+ 0x04B8, 0x0475, 0x0435, 0x03F8, 0x03BF, 0x038A, 0x0356, 0x0326, 0x02F9,
+ 0x02CF, 0x02A6, 0x0280, 0x025C, 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5,
+ 0x01AB, 0x0193, 0x017D, 0x0167, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D,
+ 0x00FE, 0x00F0, 0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0,
+ 0x0097, 0x008F, 0x0087, 0x007F, 0x0078, 0x0070, 0x0060, 0x0050, 0x0040,
+ 0x0030, 0x0020, 0x0010, 0x0000, 0x0000, 0x0020, 0x2020, 0x2020, 0x2020,
+ 0x2020, 0x3030, 0x3030, 0x3020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
+ 0x2020, 0x2020, 0x2020, 0x2090, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040,
+ 0x4040, 0x4040, 0x400C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C40, 0x4040,
+ 0x4040, 0x4040, 0x0909, 0x0909, 0x0909, 0x0101, 0x0101, 0x0101, 0x0101,
+ 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x4040, 0x4040, 0x4040,
+ 0x0A0A, 0x0A0A, 0x0A0A, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202,
+ 0x0202, 0x0202, 0x0202, 0x0202, 0x4040, 0x4040, 0x2000};
+
+Infogrames::Infogrames(Instruments &ins, bool stereo, int rate) :
+ Paula(stereo, rate, rate/80) {
+ _instruments = &ins;
_data = 0;
_repCount = -1;
@@ -264,7 +288,6 @@ void Infogrames::init() {
_period = 0;
_sample = 0;
_speedCounter = _speed;
- _newVol = 0x3F;
for (i = 0; i < 4; i++) {
_chn[i].cmds = 0;
@@ -285,28 +308,20 @@ void Infogrames::init() {
_chn[i].periodSlide.flags = 0;
_chn[i].periodSlide.curDelay1 = 0;
_chn[i].periodSlide.curDelay2 = 0;
- _chn[i].curPeriod = 0;
_chn[i].period = 0;
- _chn[i].curCmdBlock = 0;
- _chn[i].flags = 0;
+ _chn[i].flags = 0x81;
_chn[i].ticks = 0;
_chn[i].tickCount = 0;
_chn[i].periodMod = 0;
- _chn[i].field_2B = 0;
- _chn[i].field_2C = 0;
- _chn[i].field_2F = 0;
}
- for (i = 0; i < 4; i++) {
- _chn[i].flags = 0x81;
- _chn[i].field_2B = 0x3F;
- _chn[i].field_2F = 0x3F;
- }
+ _end = _data == 0;
}
void Infogrames::reset() {
int i;
+ stopPlay();
init();
_volSlideBlocks = 0;
@@ -315,8 +330,6 @@ void Infogrames::reset() {
_cmdBlocks = 0;
_speedCounter = 0;
_speed = 0;
- _newVol = 0;
- _field_1E = 8;
for (i = 0; i < 4; i++)
_chn[i].cmdBlockIndices = 0;
@@ -350,11 +363,8 @@ bool Infogrames::load(Common::SeekableReadStream &dum) {
for (i = 0; i < 4; i++) {
_chn[i].cmdBlockIndices = _subSong + dataStr.readUint16BE();
_chn[i].flags = 0x81;
- _chn[i].field_2B = 0x3F;
- _chn[i].field_2F = 0x3F;
}
_cmdBlocks = _data + dataStr.pos() + 2;
- _newVol = 0x3F;
if ((_volSlideBlocks > (_data + size)) ||
(_periodSlideBlocks > (_data + size)) ||
@@ -366,10 +376,11 @@ bool Infogrames::load(Common::SeekableReadStream &dum) {
return false;
_end = false;
+ _playing = true;
return true;
}
-void Infogrames::unload(bool destroyInstruments) {
+void Infogrames::unload(void) {
stopPlay();
if (_data)
@@ -379,12 +390,6 @@ void Infogrames::unload(bool destroyInstruments) {
clearVoices();
reset();
- if (destroyInstruments) {
- if (_instruments)
- delete _instruments;
- _instruments = 0;
- }
-
_end = true;
}
@@ -397,28 +402,16 @@ void Infogrames::getNextSample(Channel &chn) {
if (chn.flags & 64)
return;
- if (chn.field_2B != chn.field_2F) {
- chn.field_2C++;
- if (chn.field_2C > _field_1E) {
- chn.field_2C = 0;
- if (chn.field_2F <= chn.field_2B)
- chn.field_2B--;
- else
- chn.field_2B++;
- }
- }
-
if (chn.flags & 1) {
chn.flags &= ~1;
chn.cmdBlocks = chn.cmdBlockIndices;
- chn.curCmdBlock = 0;
} else {
chn.flags &= ~1;
if (_speedCounter == 0)
chn.ticks--;
if (chn.ticks != 0) {
- _volume = MAX(0, tune(chn.volSlide, 0) - (0x3F - MAX(chn.field_2B, _newVol)));
- _period = tune(chn.periodSlide, chn.curPeriod);
+ _volume = MAX((int16) 0, tune(chn.volSlide, 0));
+ _period = tune(chn.periodSlide, chn.period);
return;
} else {
chn.ticks = chn.tickCount;
@@ -430,8 +423,8 @@ void Infogrames::getNextSample(Channel &chn) {
while (cont || ((cmdBlock = *chn.cmdBlocks) != 0xFF)) {
if (!cont) {
chn.cmdBlocks++;
- chn.curCmdBlock++;
- chn.cmds = _subSong + READ_BE_UINT16(_cmdBlocks + (cmdBlock * 2));
+ chn.cmds = _subSong +
+ READ_BE_UINT16(_cmdBlocks + (cmdBlock * 2));
} else
cont = false;
while ((cmd = *chn.cmds) != 0xFF) {
@@ -463,7 +456,8 @@ void Infogrames::getNextSample(Channel &chn) {
chn.periodMod = (int8) *chn.cmds++;
break;
case 1: // Set continuous period slide
- chn.periodSlide.data = _periodSlideBlocks + *chn.cmds++ * 13 + 1;
+ chn.periodSlide.data =
+ _periodSlideBlocks + *chn.cmds++ * 13 + 1;
chn.periodSlide.amount = 0;
chn.periodSlide.dataOffset = 0;
chn.periodSlide.finetunePos = 0;
@@ -473,7 +467,8 @@ void Infogrames::getNextSample(Channel &chn) {
chn.periodSlide.flags = 0x81;
break;
case 2: // Set non-continuous period slide
- chn.periodSlide.data = _periodSlideBlocks + *chn.cmds++ * 13 + 1;
+ chn.periodSlide.data =
+ _periodSlideBlocks + *chn.cmds++ * 13 + 1;
chn.periodSlide.amount = 0;
chn.periodSlide.dataOffset = 0;
chn.periodSlide.finetunePos = 0;
@@ -492,7 +487,6 @@ void Infogrames::getNextSample(Channel &chn) {
} else { // 0xxxxxxx - Set period
if (cmd != 0)
cmd += chn.periodMod;
- chn.curPeriod = periods[cmd];
chn.period = periods[cmd];
chn.volSlide.dataOffset = 0;
chn.volSlide.finetunePos = 0;
@@ -508,20 +502,18 @@ void Infogrames::getNextSample(Channel &chn) {
chn.periodSlide.curDelay2 = 0;
chn.periodSlide.flags |= 1;
chn.periodSlide.flags &= ~4;
- _volume = MAX(0, tune(chn.volSlide, 0) - (0x3F - MAX(chn.field_2B, _newVol)));
- _period = tune(chn.periodSlide, chn.curPeriod);
+ _volume = MAX((int16) 0, tune(chn.volSlide, 0));
+ _period = tune(chn.periodSlide, chn.period);
return;
}
}
}
- if (chn.flags & 32) {
- chn.cmdBlocks = chn.cmdBlockIndices;
- chn.curCmdBlock = 0;
- } else {
+ if (!(chn.flags & 32)) {
chn.flags |= 0x40;
_volume = 0;
return;
- }
+ } else
+ chn.cmdBlocks = chn.cmdBlockIndices;
}
}
@@ -586,7 +578,8 @@ void Infogrames::interrupt() {
_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].lengthRepeat =
+ _instruments->_samples[_sample].lengthRepeat;
_voice[chn].offset = 0;
_sample = 0xFF;
}
@@ -600,10 +593,12 @@ void Infogrames::interrupt() {
if (_repCount > 0) {
_repCount--;
init();
- } else if (_repCount == -1)
- init();
- else
+ } else if (_repCount != -1) {
_end = true;
+ _playing = false;
+ }
+ else
+ init();
}
}
@@ -698,7 +693,8 @@ void Adlib::premixerCall(int16 *buf, uint len) {
uint datalen = len;
while (datalen && _playing) {
if (_samplesTillPoll) {
- render = (datalen > _samplesTillPoll) ? (_samplesTillPoll) : (datalen);
+ render = (datalen > _samplesTillPoll) ?
+ (_samplesTillPoll) : (datalen);
datalen -= render;
_samplesTillPoll -= render;
YM3812UpdateOne(_opl, data, render);
@@ -759,10 +755,10 @@ void Adlib::setFreqs(void) {
// Run through the 12 columns
for (col = 0; col < 12; col ++) {
if (!col)
- val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) * 9 / 0x1B503;
+ val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) *
+ 9 / 0x1B503;
_freqs[lin][col] = (short)((val + 4) >> 3);
val = val * 0x6A / 0x64;
- // val = val * 392 / 370;
}
}
}
@@ -810,7 +806,8 @@ void Adlib::setVoice(byte voice, byte instr, bool set) {
writeOPL(0x08, 0x00);
writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F));
if (!i)
- writeOPL(0xC0 | voice , ((strct[2] & 7) << 1) | (1 - (strct[12] & 1)));
+ writeOPL(0xC0 | voice,
+ ((strct[2] & 7) << 1) | (1 - (strct[12] & 1)));
writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF));
writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF));
writeOPL(0x20 | channel, ((strct[9] & 1) << 7) |
@@ -971,14 +968,16 @@ void Adlib::pollMusic(void) {
_samplesTillPoll = 0;
return;
default:
- warning("Unknown special command in ADL, stopping playback: %X", instr & 0x0F);
+ warning("Unknown special command in ADL, stopping playback: %X",
+ instr & 0x0F);
_repCount = 0;
_ended = true;
break;
}
break;
default:
- warning("Unknown command in ADL, stopping playback: %X", instr & 0xF0);
+ warning("Unknown command in ADL, stopping playback: %X",
+ instr & 0xF0);
_repCount = 0;
_ended = true;
break;
@@ -1000,13 +999,6 @@ void Adlib::pollMusic(void) {
_samplesTillPoll = tempo * (_rate / 1000);
}
-void Adlib::startPlay(void) {
- if (!_data)
- return;
-
- _playing = true;
-}
-
void Adlib::playBgMusic(void) {
for (int i = 0; i < ARRAYSIZE(_tracks); i++)
if (!scumm_stricmp(_vm->_game->_curTotFile, _tracks[i][0])) {