Some work on the Bochs sound support.
- OPL3: Added support to change the samplerate of the generator. - SDL sound: convert wave packet to 16 Bit signed stereo format. - Increased the maximum size of a single wave packet for playbck/recording.
This commit is contained in:
parent
55f7c7542b
commit
add5b1e61d
@ -991,7 +991,7 @@ static void OPL_INLINE clipit16(Bit32s ival, Bit16s* outval)
|
||||
opl_active = 1;
|
||||
#endif
|
||||
|
||||
bx_bool adlib_getsample(Bit16s* sndptr, Bits numsamples)
|
||||
bx_bool adlib_getsample(Bit16u rate, Bit16s* sndptr, Bits numsamples)
|
||||
{
|
||||
Bits i, endsamples;
|
||||
op_type* cptr;
|
||||
@ -1009,6 +1009,10 @@ bx_bool adlib_getsample(Bit16s* sndptr, Bits numsamples)
|
||||
|
||||
Bits samples_to_process = numsamples;
|
||||
|
||||
if (rate != (Bit16u)int_samplerate) {
|
||||
adlib_init(rate);
|
||||
}
|
||||
|
||||
for (Bits cursmp=0; cursmp<samples_to_process; cursmp+=endsamples) {
|
||||
endsamples = samples_to_process-cursmp;
|
||||
if (endsamples>BLOCKBUF_SIZE) endsamples = BLOCKBUF_SIZE;
|
||||
|
@ -204,7 +204,7 @@ static Bit32u generator_add; // should be a chip parameter
|
||||
// general functions
|
||||
void adlib_init(Bit32u samplerate);
|
||||
void adlib_write(Bitu idx, Bit8u val);
|
||||
bx_bool adlib_getsample(Bit16s* sndptr, Bits numsamples);
|
||||
bx_bool adlib_getsample(Bit16u rate, Bit16s* sndptr, Bits numsamples);
|
||||
|
||||
Bitu adlib_reg_read(Bitu port);
|
||||
void adlib_write_index(Bitu port, Bit8u val);
|
||||
|
@ -2364,7 +2364,7 @@ void bx_sb16_c::opl_settimermask(int value, int chipid)
|
||||
|
||||
Bit32u bx_sb16_c::fmopl_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
{
|
||||
bx_bool ret = adlib_getsample((Bit16s*)buffer, len / 4);
|
||||
bx_bool ret = adlib_getsample(rate, (Bit16s*)buffer, len / 4);
|
||||
return ret ? len : 0;
|
||||
}
|
||||
|
||||
|
@ -20,10 +20,9 @@
|
||||
|
||||
// Common code for sound lowlevel modules
|
||||
|
||||
// this is the size of a sound packet used for sending and receiving
|
||||
// it should not be too large to avoid lag, and not too
|
||||
// small to avoid unnecessary overhead.
|
||||
#define BX_SOUNDLOW_WAVEPACKETSIZE 8192
|
||||
// This is the maximum size of a wave data packet.
|
||||
// It should be large enough for 0.1 seconds of playback or recording.
|
||||
#define BX_SOUNDLOW_WAVEPACKETSIZE 19200
|
||||
|
||||
// Definitions for the output functions
|
||||
#define BX_SOUNDLOW_OK 0
|
||||
|
@ -157,35 +157,83 @@ int bx_sound_sdl_c::waveready()
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
void bx_sound_sdl_c::convert_wavedata(Bit8u *src, int srcsize, Bit8u *dst, int dstsize, bx_pcm_param_t *param)
|
||||
{
|
||||
int i, j;
|
||||
Bit8u xor_val;
|
||||
|
||||
xor_val = (param->format & 1) ? 0x00 : 0x80;
|
||||
if (param->bits == 16) {
|
||||
if ((param->format & 1) && (param->channels == 2)) {
|
||||
memcpy(dst, src, dstsize);
|
||||
} else if (param->channels == 2) {
|
||||
j = 0;
|
||||
for (i = 0; i < srcsize; i+=2) {
|
||||
dst[j++] = src[i];
|
||||
dst[j++] = src[i+1] ^ xor_val;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
for (i = 0; i < srcsize; i+=2) {
|
||||
dst[j++] = src[i];
|
||||
dst[j++] = src[i+1] ^ xor_val;
|
||||
dst[j++] = src[i];
|
||||
dst[j++] = src[i+1] ^ xor_val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (param->channels == 2) {
|
||||
j = 0;
|
||||
for (i = 0; i < srcsize; i++) {
|
||||
dst[j++] = 0;
|
||||
dst[j++] = src[i] ^ xor_val;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
for (i = 0; i < srcsize; i++) {
|
||||
dst[j++] = 0;
|
||||
dst[j++] = src[i] ^ xor_val;
|
||||
dst[j++] = 0;
|
||||
dst[j++] = src[i] ^ xor_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bx_sound_sdl_c::sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *param)
|
||||
{
|
||||
int ret = BX_SOUNDLOW_OK;
|
||||
int tmpsize;
|
||||
int size;
|
||||
int bsize, len2, ssize = 1;
|
||||
|
||||
if (memcmp(param, &pcm_param, sizeof(bx_pcm_param_t)) != 0) {
|
||||
startwaveplayback(param->samplerate, param->bits, param->channels == 2,
|
||||
param->format);
|
||||
startwaveplayback(param->samplerate, 16, 1, 1);
|
||||
pcm_param = *param;
|
||||
}
|
||||
len2 = length;
|
||||
if (param->bits == 8) ssize = 2;
|
||||
if (param->channels == 1) ssize *= 2;
|
||||
len2 = length * ssize;
|
||||
SDL_LockAudio();
|
||||
if (WaveOpen) {
|
||||
size = audio_buffer.optr - audio_buffer.iptr;
|
||||
if (size <= 0) {
|
||||
size += BX_SOUND_SDL_BUFSIZE;
|
||||
bsize = audio_buffer.optr - audio_buffer.iptr;
|
||||
if (bsize <= 0) {
|
||||
bsize += BX_SOUND_SDL_BUFSIZE;
|
||||
}
|
||||
if (size < length) {
|
||||
BX_ERROR(("SDL: audio buffer overflow: l=%d s=%d", length, size));
|
||||
ret = BX_SOUNDLOW_ERR;
|
||||
} else {
|
||||
if ((audio_buffer.iptr + length) > BX_SOUND_SDL_BUFSIZE) {
|
||||
if (bsize < len2) {
|
||||
BX_ERROR(("SDL: audio buffer overflow: l=%d s=%d", len2, bsize));
|
||||
len2 = (bsize > ssize) ? bsize - ssize : 0;
|
||||
}
|
||||
if (len2 > 0) {
|
||||
if ((audio_buffer.iptr + len2) > BX_SOUND_SDL_BUFSIZE) {
|
||||
tmpsize = BX_SOUND_SDL_BUFSIZE - audio_buffer.iptr;
|
||||
memcpy(audio_buffer.data+audio_buffer.iptr, data, tmpsize);
|
||||
memcpy(audio_buffer.data, data+tmpsize, length-tmpsize);
|
||||
audio_buffer.iptr = length-tmpsize;
|
||||
len2 -= tmpsize;
|
||||
convert_wavedata(data, tmpsize/ssize, audio_buffer.data+audio_buffer.iptr, tmpsize, param);
|
||||
convert_wavedata(data+tmpsize/ssize, len2/ssize, audio_buffer.data, len2, param);
|
||||
audio_buffer.iptr = len2;
|
||||
} else {
|
||||
memcpy(audio_buffer.data+audio_buffer.iptr, data, length);
|
||||
audio_buffer.iptr += length;
|
||||
convert_wavedata(data, length, audio_buffer.data+audio_buffer.iptr, len2, param);
|
||||
audio_buffer.iptr += len2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
virtual void unregister_wave_callback(int callback_id);
|
||||
void get_wave_data(Bit8u *stream, int len);
|
||||
private:
|
||||
void convert_wavedata(Bit8u *src, int srcsize, Bit8u *dst, int dstsize, bx_pcm_param_t *param);
|
||||
bx_bool WaveOpen;
|
||||
SDL_AudioSpec fmt;
|
||||
int cb_count;
|
||||
|
Loading…
Reference in New Issue
Block a user