mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-02-04 05:15:21 +00:00
(svn r13695) -Fix [FS#2120]: in some cases the (sound) mixer could overflow causing artefacts in the sound.
This commit is contained in:
parent
e74743227b
commit
53436082a2
@ -5,6 +5,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
#include "mixer.h"
|
#include "mixer.h"
|
||||||
|
#include "core/math_func.hpp"
|
||||||
|
|
||||||
struct MixerChannel {
|
struct MixerChannel {
|
||||||
bool active;
|
bool active;
|
||||||
@ -19,8 +20,8 @@ struct MixerChannel {
|
|||||||
uint32 samples_left;
|
uint32 samples_left;
|
||||||
|
|
||||||
/* Mixing volume */
|
/* Mixing volume */
|
||||||
uint volume_left;
|
int volume_left;
|
||||||
uint volume_right;
|
int volume_right;
|
||||||
|
|
||||||
uint flags;
|
uint flags;
|
||||||
};
|
};
|
||||||
@ -28,14 +29,22 @@ struct MixerChannel {
|
|||||||
static MixerChannel _channels[8];
|
static MixerChannel _channels[8];
|
||||||
static uint32 _play_rate;
|
static uint32 _play_rate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The theoretical maximum volume for a single sound sample. Multiple sound
|
||||||
|
* samples should not exceed this limit as it will sound too loud. It also
|
||||||
|
* stops overflowing when too many sounds are played at the same time, which
|
||||||
|
* causes an even worse sound quality.
|
||||||
|
*/
|
||||||
|
static const int MAX_VOLUME = 128 * 128;
|
||||||
|
|
||||||
|
|
||||||
static void mix_int8_to_int16(MixerChannel *sc, int16 *buffer, uint samples)
|
static void mix_int8_to_int16(MixerChannel *sc, int16 *buffer, uint samples)
|
||||||
{
|
{
|
||||||
int8 *b;
|
int8 *b;
|
||||||
uint32 frac_pos;
|
uint32 frac_pos;
|
||||||
uint32 frac_speed;
|
uint32 frac_speed;
|
||||||
uint volume_left;
|
int volume_left;
|
||||||
uint volume_right;
|
int volume_right;
|
||||||
|
|
||||||
if (samples > sc->samples_left) samples = sc->samples_left;
|
if (samples > sc->samples_left) samples = sc->samples_left;
|
||||||
sc->samples_left -= samples;
|
sc->samples_left -= samples;
|
||||||
@ -50,15 +59,15 @@ static void mix_int8_to_int16(MixerChannel *sc, int16 *buffer, uint samples)
|
|||||||
if (frac_speed == 0x10000) {
|
if (frac_speed == 0x10000) {
|
||||||
/* Special case when frac_speed is 0x10000 */
|
/* Special case when frac_speed is 0x10000 */
|
||||||
do {
|
do {
|
||||||
buffer[0] += *b * volume_left >> 8;
|
buffer[0] = Clamp(buffer[0] + (*b * volume_left >> 8), -MAX_VOLUME, MAX_VOLUME);
|
||||||
buffer[1] += *b * volume_right >> 8;
|
buffer[0] = Clamp(buffer[1] + (*b * volume_right >> 8), -MAX_VOLUME, MAX_VOLUME);
|
||||||
b++;
|
b++;
|
||||||
buffer += 2;
|
buffer += 2;
|
||||||
} while (--samples > 0);
|
} while (--samples > 0);
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
buffer[0] += *b * volume_left >> 8;
|
buffer[0] = Clamp(buffer[0] + (*b * volume_left >> 8), -MAX_VOLUME, MAX_VOLUME);
|
||||||
buffer[1] += *b * volume_right >> 8;
|
buffer[0] = Clamp(buffer[1] + (*b * volume_right >> 8), -MAX_VOLUME, MAX_VOLUME);
|
||||||
buffer += 2;
|
buffer += 2;
|
||||||
frac_pos += frac_speed;
|
frac_pos += frac_speed;
|
||||||
b += frac_pos >> 16;
|
b += frac_pos >> 16;
|
||||||
|
Loading…
Reference in New Issue
Block a user