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
This commit is contained in:
Lionel Ulmer 2002-05-18 14:53:19 +00:00
parent 53f993be44
commit 3b4c6ceb0f
4 changed files with 85 additions and 31 deletions

View File

@ -829,7 +829,7 @@ bool OSystem_SDL::set_sound_proc(void *param, SoundProc *proc, byte format) {
desired.freq = SAMPLES_PER_SEC;
desired.format = AUDIO_S16SYS;
desired.channels = 1;
desired.channels = 2;
desired.samples = 2048;
desired.callback = proc;
desired.userdata = param;

View File

@ -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++;
}

View File

@ -131,9 +131,12 @@ public:
/* start playing a raw sound */
enum {
FLAG_AUTOFREE = 1,
FLAG_UNSIGNED = 2, /* unsigned samples */
FLAG_FILE = 4, /* sound is a FILE * that's read from */
/* Do *NOT* change any of these flags without looking at the code in mixer.cpp */
FLAG_UNSIGNED = 1, /* unsigned samples */
FLAG_STEREO = 2, /* sound is in stereo */
FLAG_16BITS = 4, /* sound is 16 bits wide */
FLAG_AUTOFREE = 8, /* sound buffer is freed automagically at the end of playing */
FLAG_FILE = 16, /* sound is a FILE * that's read from */
};
int play_raw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags);
#ifdef COMPRESSED_SOUND_FILE

11
x11.cpp
View File

@ -256,21 +256,18 @@ static void *sound_and_music_thread(void *params)
sched_yield();
while (1) {
unsigned short *buf = (unsigned short *)sound_buffer;
unsigned char *buf = (unsigned char *)sound_buffer;
int size, written;
sound_proc(proc_param, (byte *)sound_buffer, FRAG_SIZE >> 1);
/* Now convert to stereo */
for (int i = ((FRAG_SIZE >> 2) - 1); i >= 0; i--) {
buf[2 * i + 1] = buf[2 * i] = buf[i];
}
sound_proc(proc_param, (byte *)sound_buffer, FRAG_SIZE);
#ifdef CAPTURE_SOUND
fwrite(buf, 2, FRAG_SIZE >> 1, f);
fflush(f);
#endif
size = FRAG_SIZE;
while (size > 0) {
written = write(sound_fd, sound_buffer, size);
written = write(sound_fd, buf, size);
buf += written;
size -= written;
}
}