aboutsummaryrefslogtreecommitdiff
path: root/sound/mixer.cpp
diff options
context:
space:
mode:
authorLionel Ulmer2002-05-18 14:53:19 +0000
committerLionel Ulmer2002-05-18 14:53:19 +0000
commit3b4c6ceb0f621b68a5a44922d7218987faedb10e (patch)
tree55d9b1ff3d1cb7fb60612360eef2d26b87167d86 /sound/mixer.cpp
parent53f993be44ac34c3f17677cb432a366dec962824 (diff)
downloadscummvm-rg350-3b4c6ceb0f621b68a5a44922d7218987faedb10e.tar.gz
scummvm-rg350-3b4c6ceb0f621b68a5a44922d7218987faedb10e.tar.bz2
scummvm-rg350-3b4c6ceb0f621b68a5a44922d7218987faedb10e.zip
Added infrastructure to support more than 8 bit signed / unsigned RAW
mixers. Porters, beware, the default configuration is now 16 bit stereo instead of 16 mono as before (I changed X11 and SDL but no others). I did not add support for any other format yet, I will let Endy do it when he needs it :-) svn-id: r4348
Diffstat (limited to 'sound/mixer.cpp')
-rw-r--r--sound/mixer.cpp94
1 files changed, 74 insertions, 20 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp
index 9473ddd69d..a47965ca65 100644
--- a/sound/mixer.cpp
+++ b/sound/mixer.cpp
@@ -84,14 +84,20 @@ int SoundMixer::play_mp3_cdtrack(PlayingSoundHandle *handle, FILE* file, mad_tim
void SoundMixer::mix(int16 *buf, uint len) {
- if (_paused)
+ if (_paused) {
+ memset(buf, 0, 2 * len * sizeof(int16));
return;
+ }
if (_premix_proc) {
+ int i;
_premix_proc(_premix_param, buf, len);
+ for (i = (len - 1); i >= 0; i--) {
+ buf[2 * i] = buf[2 * i + 1] = buf[i];
+ }
} else {
/* no premixer available, zero the buf out */
- memset(buf, 0, len * sizeof(int16));
+ memset(buf, 0, 2 * len * sizeof(int16));
}
/* now mix all channels */
@@ -101,7 +107,7 @@ void SoundMixer::mix(int16 *buf, uint len) {
}
void SoundMixer::on_generate_samples(void *s, byte *samples, int len) {
- ((SoundMixer*)s)->mix((int16*)samples, len>>1);
+ ((SoundMixer*)s)->mix((int16*)samples, len>>2);
}
bool SoundMixer::bind_to_system(OSystem *syst) {
@@ -207,6 +213,64 @@ void SoundMixer::Channel_RAW::append(void *data, uint32 len) {
_mixer->_paused = false; /* Mix again now */
}
+static void mix_signed_mono_8(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ uint32 fp_pos = *fp_pos_ptr;
+ byte *s = *s_ptr;
+ do {
+ fp_pos += fp_speed;
+ *data++ += vol_tab[*s];
+ *data++ += vol_tab[*s];
+ s += fp_pos >> 16;
+ fp_pos &= 0x0000FFFF;
+ } while (--len);
+
+ *fp_pos_ptr = fp_pos;
+ *s_ptr = s;
+}
+static void mix_unsigned_mono_8(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ uint32 fp_pos = *fp_pos_ptr;
+ byte *s = *s_ptr;
+ do {
+ fp_pos += fp_speed;
+ *data++ += vol_tab[*s ^ 0x80];
+ *data++ += vol_tab[*s ^ 0x80];
+ s += fp_pos >> 16;
+ fp_pos &= 0x0000FFFF;
+ } while (--len);
+
+ *fp_pos_ptr = fp_pos;
+ *s_ptr = s;
+}
+static void mix_signed_stereo_8(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ warning("Mixing stereo signed 8 bit is not supported yet ");
+}
+static void mix_unsigned_stereo_8(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ warning("Mixing stereo unsigned 8 bit is not supported yet ");
+}
+static void mix_signed_mono_16(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ warning("Mixing mono signed 16 bit is not supported yet ");
+}
+static void mix_unsigned_mono_16(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ warning("Mixing mono unsigned 16 bit is not supported yet ");
+}
+static void mix_signed_stereo_16(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ warning("Mixing stereo signed 16 bit is not supported yet ");
+}
+static void mix_unsigned_stereo_16(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) {
+ warning("Mixing stereo unsigned 16 bit is not supported yet ");
+}
+
+static void (*mixer_helper_table[16])(int16 *data, uint len, byte **s_ptr, uint32 *fp_pos_ptr, int fp_speed, const int16 *vol_tab) = {
+ mix_signed_mono_8,
+ mix_unsigned_mono_8,
+ mix_signed_stereo_8,
+ mix_unsigned_stereo_8,
+ mix_signed_mono_16,
+ mix_unsigned_mono_16,
+ mix_signed_stereo_16,
+ mix_unsigned_stereo_16
+};
+
void SoundMixer::Channel_RAW::mix(int16 *data, uint len) {
byte *s, *s_org = NULL;
uint32 fp_pos;
@@ -245,21 +309,7 @@ void SoundMixer::Channel_RAW::mix(int16 *data, uint len) {
const uint32 fp_speed = _fp_speed;
const int16 *vol_tab = _mixer->_volume_table;
- if (_flags & FLAG_UNSIGNED) {
- do {
- fp_pos += fp_speed;
- *data++ += vol_tab[*s ^ 0x80];
- s += fp_pos >> 16;
- fp_pos &= 0x0000FFFF;
- } while (--len);
- } else {
- do {
- fp_pos += fp_speed;
- *data++ += vol_tab[*s];
- s += fp_pos >> 16;
- fp_pos &= 0x0000FFFF;
- } while (--len);
- }
+ mixer_helper_table[_flags & 0x07](data, len, &s, &fp_pos, fp_speed, vol_tab);
_pos = s - (byte*) _ptr;
_fp_pos = fp_pos;
@@ -345,7 +395,9 @@ void SoundMixer::Channel_MP3::mix(int16 *data, uint len) {
if (_silence_cut > 0) {
_silence_cut--;
} else {
- *data++ += (int16) ((scale_sample(*ch++) * volume) / 32);
+ int16 sample = (int16) ((scale_sample(*ch++) * volume) / 32);
+ *data++ += sample;
+ *data++ += sample;
len--;
}
_pos_in_frame++;
@@ -463,7 +515,9 @@ void SoundMixer::Channel_MP3_CDMUSIC::mix(int16 *data, uint len) {
// Get samples, play samples ...
ch = _synth.pcm.samples[0] + _pos_in_frame;
while ((_pos_in_frame < _synth.pcm.length) && (len > 0)) {
- *data++ += (int16) ((scale_sample(*ch++) * volume) / 32);
+ int16 sample = (int16) ((scale_sample(*ch++) * volume) / 32);
+ *data++ += sample;
+ *data++ += sample;
len--;
_pos_in_frame++;
}