diff options
-rw-r--r-- | engines/agi/sound.cpp | 19 | ||||
-rw-r--r-- | engines/agi/sound.h | 24 |
2 files changed, 24 insertions, 19 deletions
diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index a4bd9aca73..e6dff9fea2 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -420,7 +420,7 @@ void SoundMgr::startSound(int resnum, int flag) { } chn[i].ins = waveform; chn[i].size = WAVEFORM_SIZE; - chn[i].ptr = (struct AgiNote *)(song + (song[i << 1] | (song[(i << 1) + 1] << 8))); + chn[i].ptr = song + READ_LE_UINT16(song + i * 2); chn[i].timer = 0; chn[i].vol = 0; chn[i].end = 0; @@ -586,7 +586,7 @@ void SoundMgr::playMidiSound() { } chn[0].timer = *p++; - chn[0].ptr = (struct AgiNote *)p; + chn[0].ptr = p; if (*p >= 0xfc) { debugC(3, kDebugLevelSound, "end of sequence"); @@ -603,24 +603,25 @@ void SoundMgr::playSampleSound() { #endif /* USE_IIGS_SOUND */ void SoundMgr::playAgiSound() { - int i, freq; + int i; + AgiNote note; for (playing = i = 0; i < (_vm->_soundemu == SOUND_EMU_PC ? 1 : 4); i++) { playing |= !chn[i].end; + note.read(chn[i].ptr); // Read a single note (Doesn't advance the pointer) if (chn[i].end) continue; if ((--chn[i].timer) <= 0) { stopNote(i); - freq = ((chn[i].ptr->frq0 & 0x3f) << 4) | (int)(chn[i].ptr->frq1 & 0x0f); - if (freq) { - uint8 v = chn[i].ptr->vol & 0x0f; - playNote(i, freq * 10, v == 0xf ? 0 : 0xff - (v << 1)); + if (note.freqDiv != 0) { + int volume = (note.attenuation == 0x0F) ? 0 : (0xFF - note.attenuation * 2); + playNote(i, note.freqDiv * 10, volume); } - chn[i].timer = ((int)chn[i].ptr->durHi << 8) | chn[i].ptr->durLo; + chn[i].timer = note.duration; if (chn[i].timer == 0xffff) { chn[i].end = 1; @@ -634,7 +635,7 @@ void SoundMgr::playAgiSound() { } #endif } - chn[i].ptr++; + chn[i].ptr += 5; // Advance the pointer to the next note data (5 bytes per note) } } } diff --git a/engines/agi/sound.h b/engines/agi/sound.h index b2201a3f67..6d7e71ef8e 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -177,21 +177,25 @@ struct IIgsSampleHeader { bool finalize(Common::SeekableReadStream &uint8Wave); }; -#include "common/pack-start.h" - /** * AGI sound note structure. */ struct AgiNote { - uint8 durLo; /**< LSB of note duration */ - uint8 durHi; /**< MSB of note duration */ - uint8 frq0; /**< LSB of note frequency */ - uint8 frq1; /**< MSB of note frequency */ - uint8 vol; /**< note volume */ + uint16 duration; ///< Note duration + uint16 freqDiv; ///< Note frequency divisor (10-bit) + uint8 attenuation; ///< Note volume attenuation (4-bit) + + /** Reads an AgiNote through the given pointer. */ + void read(uint8 *ptr) { + duration = READ_LE_UINT16(ptr); + uint16 freqByte0 = *(ptr + 2); // Bits 4-9 of the frequency divisor + uint16 freqByte1 = *(ptr + 3); // Bits 0-3 of the frequency divisor + // Merge the frequency divisor's bits together into a single variable + freqDiv = ((freqByte0 & 0x3F) << 4) | (freqByte1 & 0x0F); + attenuation = *(ptr + 4) & 0x0F; + } }; -#include "common/pack-end.h" - /** * AGI engine sound channel structure. */ @@ -200,7 +204,7 @@ struct ChannelInfo { #define AGI_SOUND_MIDI 0x0002 #define AGI_SOUND_4CHN 0x0008 uint32 type; - struct AgiNote *ptr; + uint8 *ptr; // Pointer to the AgiNote data int16 *ins; int32 size; uint32 phase; |