mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-22 10:17:22 +00:00
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:
parent
53f993be44
commit
3b4c6ceb0f
2
sdl.cpp
2
sdl.cpp
@ -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;
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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
11
x11.cpp
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user