aboutsummaryrefslogtreecommitdiff
path: root/backends/midi
diff options
context:
space:
mode:
authorJochen Hoenicke2003-08-15 16:40:17 +0000
committerJochen Hoenicke2003-08-15 16:40:17 +0000
commit3b75fa8d3ce712b0c696eb586f4cd341ad1fb345 (patch)
treefeaab2345e69502a85488bf2492405aee1e06df7 /backends/midi
parenta892474a4f53ae5c0755bb4b86092b79f7faccab (diff)
downloadscummvm-rg350-3b75fa8d3ce712b0c696eb586f4cd341ad1fb345.tar.gz
scummvm-rg350-3b75fa8d3ce712b0c696eb586f4cd341ad1fb345.tar.bz2
scummvm-rg350-3b75fa8d3ce712b0c696eb586f4cd341ad1fb345.zip
Changed on_timer frequency in adlib so V3 SFX are correctly timed.
Changed V3 conversion code to adapt to the new (correct) speed. svn-id: r9712
Diffstat (limited to 'backends/midi')
-rw-r--r--backends/midi/adlib.cpp54
1 files changed, 40 insertions, 14 deletions
diff --git a/backends/midi/adlib.cpp b/backends/midi/adlib.cpp
index e4c5fe0df0..59b50aa2ef 100644
--- a/backends/midi/adlib.cpp
+++ b/backends/midi/adlib.cpp
@@ -25,7 +25,12 @@
#include "common/engine.h" // for warning/error/debug
#include "common/util.h"
+#define BASE_FREQ 250
+#define FIXP_SHIFT 16
+
+#ifdef DEBUG_ADLIB
static int tick;
+#endif
class MidiDriver_ADLIB;
struct AdlibVoice;
@@ -559,11 +564,7 @@ public:
void setTimerCallback(void *timer_param, void (*timer_proc) (void *));
uint32 getBaseTempo() {
-#ifdef _WIN32_WCE
- return 3991 * 2; // Sampled down to 11 kHz
-#else //_WIN32_WCE
- return 3991; // 88 samples per call (at 22 kHz mono)
-#endif //_WIN32_WCE
+ return 1000000 / BASE_FREQ;
}
MidiChannel *allocateChannel();
@@ -585,6 +586,9 @@ private:
uint16 channel_table_2[9];
int _voice_index;
int _next_tick;
+ int _samples_per_tick;
+ int _timer_p;
+ int _timer_q;
uint16 curnote_table[9];
AdlibVoice _voices[9];
AdlibPart _parts[32];
@@ -644,10 +648,16 @@ void AdlibPart::send (uint32 b) {
}
void AdlibPart::noteOff(byte note) {
+#ifdef DEBUG_ADLIB
+ debug (6, "%10d: noteOff(%d)", tick, note);
+#endif
_owner->part_key_off(this, note);
}
void AdlibPart::noteOn(byte note, byte velocity) {
+#ifdef DEBUG_ADLIB
+ debug (6, "%10d: noteOn(%d,%d)", tick, note, velocity);
+#endif
_owner->part_key_on(this, &_part_instr, note, velocity);
}
@@ -823,6 +833,8 @@ MidiDriver_ADLIB::MidiDriver_ADLIB(SoundMixer *mixer)
_parts[i].init(this, i + ((i >= 9) ? 1 : 0));
}
_percussion.init(this, 9);
+ _timer_p = 0xD69;
+ _timer_q = 0x411B;
}
int MidiDriver_ADLIB::open() {
@@ -852,6 +864,8 @@ int MidiDriver_ADLIB::open() {
adlib_write(0xBD, 0x00);
create_lookup_table();
+ _samples_per_tick = (_mixer->getOutputRate() << FIXP_SHIFT) / BASE_FREQ;
+
_mixer->setupPremix(this, premix_proc);
return 0;
@@ -929,6 +943,13 @@ uint32 MidiDriver_ADLIB::property(int prop, uint32 param) {
switch (prop) {
case PROP_OLD_ADLIB: // Older games used a different operator volume algorithm
_game_SmallHeader = (param > 0);
+ if (_game_SmallHeader) {
+ _timer_p = 473;
+ _timer_q = 1000;
+ } else {
+ _timer_p = 0xD69;
+ _timer_q = 0x411B;
+ }
return 1;
}
@@ -982,6 +1003,9 @@ void MidiDriver_ADLIB::premix_proc(void *param, int16 *buf, uint len) {
void MidiDriver_ADLIB::adlib_write(byte port, byte value) {
if (_adlib_reg_cache[port] == value)
return;
+#ifdef DEBUG_ADLIB
+ debug (6, "%10d: adlib_write[%x] = %x", tick, port, value);
+#endif
_adlib_reg_cache[port] = value;
OPLWriteReg(_opl, port, value);
@@ -992,12 +1016,12 @@ void MidiDriver_ADLIB::generate_samples(int16 *data, int len) {
do {
step = len;
- if (step > _next_tick)
- step = _next_tick;
+ if (step > (_next_tick >> FIXP_SHIFT))
+ step = (_next_tick >> FIXP_SHIFT);
YM3812UpdateOne(_opl, data, step);
- _next_tick -= step;
- if (!_next_tick) {
+ _next_tick -= step << FIXP_SHIFT;
+ if (!(_next_tick >> FIXP_SHIFT)) {
if (_timer_proc)
(*_timer_proc)(_timer_param);
on_timer();
@@ -1009,18 +1033,20 @@ void MidiDriver_ADLIB::generate_samples(int16 *data, int len) {
}
void MidiDriver_ADLIB::reset_tick() {
- _next_tick = 88;
+ _next_tick += _samples_per_tick;
}
void MidiDriver_ADLIB::on_timer() {
AdlibVoice *voice;
int i;
- _adlib_timer_counter += 0xD69;
- while (_adlib_timer_counter >= 0x411B) {
- _adlib_timer_counter -= 0x411B;
- voice = _voices;
+ _adlib_timer_counter += _timer_p;
+ while (_adlib_timer_counter >= _timer_q) {
+ _adlib_timer_counter -= _timer_q;
+#ifdef DEBUG_ADLIB
tick++;
+#endif
+ voice = _voices;
for (i = 0; i != ARRAYSIZE(_voices); i++, voice++) {
if (!voice->_part)
continue;