diff options
| author | Torbjörn Andersson | 2006-03-14 23:01:44 +0000 |
|---|---|---|
| committer | Torbjörn Andersson | 2006-03-14 23:01:44 +0000 |
| commit | 839b5d3e8665171a97cb6ca51289838de65a19a4 (patch) | |
| tree | a5d79a1e29bd0f30164d633f64efe8ede483d56b /sound | |
| parent | 59b6f0f715fb9874858feb40a22b844e42a3ce79 (diff) | |
| download | scummvm-rg350-839b5d3e8665171a97cb6ca51289838de65a19a4.tar.gz scummvm-rg350-839b5d3e8665171a97cb6ca51289838de65a19a4.tar.bz2 scummvm-rg350-839b5d3e8665171a97cb6ca51289838de65a19a4.zip | |
Added workaround in FMOPL for the pathological case where a note was turned off
while still at the very beginning of the "attack" phase. This is the very
lowest point on the attack curve, yet it would continue from the beginning of
the release curve, i.e. its very highest point. This is what caused Kyra to
often play low-frequency notes at the very beginning of a new song. (That, and
a truly bizarre function for initialising the channels.)
The proper fix would be to locate the correct point on the release curve and
continue from there. For now, though, only handle the trivial case.
svn-id: r21302
Diffstat (limited to 'sound')
| -rw-r--r-- | sound/fmopl.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/sound/fmopl.cpp b/sound/fmopl.cpp index e8f65833c9..acf17d396b 100644 --- a/sound/fmopl.cpp +++ b/sound/fmopl.cpp @@ -304,12 +304,41 @@ inline void OPL_KEYON(OPL_SLOT *SLOT) { inline void OPL_KEYOFF(OPL_SLOT *SLOT) { if( SLOT->evm > ENV_MOD_RR) { /* set envelope counter from envleope output */ - SLOT->evm = ENV_MOD_RR; - if( !(SLOT->evc & EG_DST) ) + + // WORKAROUND: The Kyra engine does something very strange when + // starting a new song. For each channel: + // + // * The release rate is set to "fastest". + // * Any note is keyed off. + // * A very low-frequency note is keyed on. + // + // Usually, what happens next is that the real notes is keyed + // on immediately, in which case there's no problem. + // + // However, if the note is again keyed off (because the channel + // begins on a rest rather than a note), the envelope counter + // was moved from the very lowest point on the attack curve to + // the very highest point on the release curve. + // + // Again, this might not be a problem, if the release rate is + // still set to "fastest". But in many cases, it had already + // been increased. And, possibly because of inaccuracies in the + // envelope generator, that would cause the note to "fade out" + // for quite a long time. + // + // What we really need is a way to find the correct starting + // point for the envelope counter, and that may be what the + // commented-out line below is meant to do. For now, simply + // handle the pathological case. + + if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST) + SLOT->evc = EG_DED; + else if( !(SLOT->evc & EG_DST) ) //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST; SLOT->evc = EG_DST; SLOT->eve = EG_DED; SLOT->evs = SLOT->evsr; + SLOT->evm = ENV_MOD_RR; } } |
