CD audio processing now performed on a dedicated thread.
Sound Blaster mixer now affect CD volume.
This commit is contained in:
parent
df2a1bfe07
commit
8b572111da
4 changed files with 143 additions and 38 deletions
42
src/sound.c
42
src/sound.c
|
|
@ -16,6 +16,7 @@
|
|||
#include "sound_wss.h"
|
||||
|
||||
#include "timer.h"
|
||||
#include "thread.h"
|
||||
|
||||
int sound_card_current = 0;
|
||||
static int sound_card_last = 0;
|
||||
|
|
@ -88,24 +89,34 @@ static int sound_poll_time = 0, sound_get_buffer_time = 0;
|
|||
|
||||
int soundon = 1;
|
||||
|
||||
static int16_t cd_buffer[CD_BUFLEN * 2];
|
||||
static thread_t *sound_cd_thread_h;
|
||||
static event_t *sound_cd_event;
|
||||
static unsigned int cd_vol_l, cd_vol_r;
|
||||
|
||||
static int16_t cd_buffer[SOUNDBUFLEN * 2];
|
||||
|
||||
void sound_cd_poll(void *p)
|
||||
void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r)
|
||||
{
|
||||
cd_vol_l = vol_l;
|
||||
cd_vol_r = vol_r;
|
||||
}
|
||||
|
||||
void sound_cd_get_buffer(int16_t *buffer, int len, void *p)
|
||||
static void sound_cd_thread(void *param)
|
||||
{
|
||||
int pos, c;
|
||||
ioctl_audio_callback(cd_buffer, (len * 2 * 441) / 480);
|
||||
pos = 0;
|
||||
|
||||
for (c = 0; c < len * 2; c+=2)
|
||||
while (1)
|
||||
{
|
||||
buffer[c] += cd_buffer[((pos >> 16) << 1)] / 2;
|
||||
buffer[c + 1] += cd_buffer[((pos >> 16) << 1) + 1] / 2;
|
||||
pos += 60211; //(44100 * 65536) / 48000;
|
||||
int c;
|
||||
|
||||
thread_wait_event(sound_cd_event, -1);
|
||||
ioctl_audio_callback(cd_buffer, CD_BUFLEN*2);
|
||||
if (soundon)
|
||||
{
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2)
|
||||
{
|
||||
cd_buffer[c] = ((int32_t)cd_buffer[c] * cd_vol_l) / 65535;
|
||||
cd_buffer[c+1] = ((int32_t)cd_buffer[c+1] * cd_vol_r) / 65535;
|
||||
}
|
||||
givealbuffer_cd(cd_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +128,9 @@ void sound_init()
|
|||
inital();
|
||||
|
||||
outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int16_t));
|
||||
|
||||
sound_cd_event = thread_create_event();
|
||||
sound_cd_thread_h = thread_create(sound_cd_thread, NULL);
|
||||
}
|
||||
|
||||
void sound_add_handler(void (*poll)(void *p), void (*get_buffer)(int16_t *buffer, int len, void *p), void *p)
|
||||
|
|
@ -154,6 +168,8 @@ void sound_get_buffer(void *priv)
|
|||
fwrite(outbuffer,(SOUNDBUFLEN)*2*2,1,soundf);*/
|
||||
|
||||
if (soundon) givealbuffer(outbuffer);
|
||||
|
||||
thread_set_event(sound_cd_event);
|
||||
}
|
||||
|
||||
void sound_reset()
|
||||
|
|
@ -163,5 +179,5 @@ void sound_reset()
|
|||
|
||||
sound_handlers_num = 0;
|
||||
|
||||
sound_add_handler(sound_cd_poll, sound_cd_get_buffer, NULL);
|
||||
sound_set_cd_volume(65535, 65535);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ char *sound_card_getname(int card);
|
|||
struct device_t *sound_card_getdevice(int card);
|
||||
int sound_card_has_config(int card);
|
||||
void sound_card_init();
|
||||
void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r);
|
||||
|
||||
#define CD_FREQ 44100
|
||||
#define CD_BUFLEN (CD_FREQ / 10)
|
||||
|
|
|
|||
|
|
@ -11,11 +11,12 @@
|
|||
|
||||
typedef struct sb_mixer_t
|
||||
{
|
||||
int master_l, master_r;
|
||||
int voice_l, voice_r;
|
||||
int fm_l, fm_r;
|
||||
int bass_l, bass_r;
|
||||
int treble_l, treble_r;
|
||||
unsigned int master_l, master_r;
|
||||
unsigned int voice_l, voice_r;
|
||||
unsigned int fm_l, fm_r;
|
||||
unsigned int cd_l, cd_r;
|
||||
unsigned int bass_l, bass_r;
|
||||
unsigned int treble_l, treble_r;
|
||||
int filter;
|
||||
|
||||
int index;
|
||||
|
|
@ -104,8 +105,8 @@ static void sb_get_buffer(int16_t *buffer, int len, void *p)
|
|||
}
|
||||
else
|
||||
{
|
||||
out_l += ((sb->dsp_buffer[c] * mixer->voice_l) / 3) >> 16;
|
||||
out_r += ((sb->dsp_buffer[c + 1] * mixer->voice_r) / 3) >> 16;
|
||||
out_l += ((int32_t)(sb->dsp_buffer[c] * mixer->voice_l) / 3) >> 16;
|
||||
out_r += ((int32_t)(sb->dsp_buffer[c + 1] * mixer->voice_r) / 3) >> 16;
|
||||
}
|
||||
|
||||
out_l = (out_l * mixer->master_l) >> 16;
|
||||
|
|
@ -148,9 +149,13 @@ void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p)
|
|||
mixer->voice_r = sb_att[(mixer->regs[0x04] & 0xf) | 0x11];
|
||||
mixer->fm_l = sb_att[(mixer->regs[0x26] >> 4) | 0x11];
|
||||
mixer->fm_r = sb_att[(mixer->regs[0x26] & 0xf) | 0x11];
|
||||
mixer->cd_l = sb_att[(mixer->regs[0x28] >> 4) | 0x11];
|
||||
mixer->cd_r = sb_att[(mixer->regs[0x28] & 0xf) | 0x11];
|
||||
mixer->filter = !(mixer->regs[0xe] & 0x20);
|
||||
mixer->bass_l = mixer->bass_r = 8;
|
||||
mixer->treble_l = mixer->treble_r = 8;
|
||||
sound_set_cd_volume((mixer->master_l * mixer->cd_l) / 65535,
|
||||
(mixer->master_r * mixer->cd_r) / 65535);
|
||||
// pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]);
|
||||
// pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r);
|
||||
if (mixer->index == 0xe)
|
||||
|
|
@ -193,6 +198,10 @@ void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p)
|
|||
mixer->regs[0x34] = ((mixer->regs[0x26] >> 4) | 0x11) << 3;
|
||||
mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) | 0x11) << 3;
|
||||
break;
|
||||
case 0x28:
|
||||
mixer->regs[0x36] = ((mixer->regs[0x28] >> 4) | 0x11) << 3;
|
||||
mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) | 0x11) << 3;
|
||||
break;
|
||||
case 0x80:
|
||||
if (val & 1) sb->dsp.sb_irqnum = 2;
|
||||
if (val & 2) sb->dsp.sb_irqnum = 5;
|
||||
|
|
@ -206,11 +215,15 @@ void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p)
|
|||
mixer->voice_r = sb_att[mixer->regs[0x33] >> 3];
|
||||
mixer->fm_l = sb_att[mixer->regs[0x34] >> 3];
|
||||
mixer->fm_r = sb_att[mixer->regs[0x35] >> 3];
|
||||
mixer->cd_l = sb_att[mixer->regs[0x36] >> 3];
|
||||
mixer->cd_r = sb_att[mixer->regs[0x37] >> 3];
|
||||
mixer->bass_l = mixer->regs[0x46] >> 4;
|
||||
mixer->bass_r = mixer->regs[0x47] >> 4;
|
||||
mixer->treble_l = mixer->regs[0x44] >> 4;
|
||||
mixer->treble_r = mixer->regs[0x45] >> 4;
|
||||
mixer->filter = 0;
|
||||
sound_set_cd_volume((mixer->master_l * mixer->cd_l) / 65535,
|
||||
(mixer->master_r * mixer->cd_r) / 65535);
|
||||
// pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]);
|
||||
// pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@
|
|||
#endif
|
||||
#endif
|
||||
#include "ibm.h"
|
||||
#include "sound.h"
|
||||
|
||||
FILE *allog;
|
||||
#ifdef USE_OPENAL
|
||||
ALuint buffers[4]; // front and back buffers
|
||||
ALuint source; // audio source
|
||||
ALenum format; // internal format
|
||||
ALuint buffers_cd[4]; // front and back buffers
|
||||
static ALuint source[2]; // audio source
|
||||
#endif
|
||||
#define FREQ 48000
|
||||
#define BUFLEN SOUNDBUFLEN
|
||||
|
|
@ -90,35 +91,51 @@ void inital()
|
|||
#ifdef USE_OPENAL
|
||||
int c;
|
||||
int16_t buf[BUFLEN*2];
|
||||
format = AL_FORMAT_STEREO16;
|
||||
|
||||
// printf("1\n");
|
||||
check();
|
||||
|
||||
// printf("2\n");
|
||||
alGenBuffers(4, buffers);
|
||||
check();
|
||||
alGenBuffers(4, buffers_cd);
|
||||
check();
|
||||
|
||||
// printf("3\n");
|
||||
alGenSources(1, &source);
|
||||
alGenSources(2, source);
|
||||
check();
|
||||
|
||||
// printf("4\n");
|
||||
alSource3f(source, AL_POSITION, 0.0, 0.0, 0.0);
|
||||
alSource3f(source, AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
alSource3f(source, AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
alSourcef (source, AL_ROLLOFF_FACTOR, 0.0 );
|
||||
alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0);
|
||||
alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 );
|
||||
alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
check();
|
||||
alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0);
|
||||
alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 );
|
||||
alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
check();
|
||||
|
||||
memset(buf,0,BUFLEN*4);
|
||||
|
||||
// printf("5\n");
|
||||
for (c=0;c<4;c++)
|
||||
alBufferData(buffers[c], AL_FORMAT_STEREO16, buf, BUFLEN*2*2, FREQ);
|
||||
alSourceQueueBuffers(source, 4, buffers);
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
alBufferData(buffers[c], AL_FORMAT_STEREO16, buf, BUFLEN*2*2, FREQ);
|
||||
alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*2, CD_FREQ);
|
||||
}
|
||||
|
||||
alSourceQueueBuffers(source[0], 4, buffers);
|
||||
check();
|
||||
alSourceQueueBuffers(source[1], 4, buffers_cd);
|
||||
check();
|
||||
// printf("6 %08X\n",source);
|
||||
alSourcePlay(source);
|
||||
alSourcePlay(source[0]);
|
||||
check();
|
||||
alSourcePlay(source[1]);
|
||||
check();
|
||||
// printf("InitAL!!! %08X\n",source);
|
||||
#endif
|
||||
|
|
@ -137,17 +154,17 @@ void givealbuffer(int16_t *buf)
|
|||
|
||||
// printf("GiveALBuffer %08X\n",source);
|
||||
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
alGetSourcei(source[0], AL_SOURCE_STATE, &state);
|
||||
|
||||
check();
|
||||
|
||||
if (state==0x1014)
|
||||
{
|
||||
alSourcePlay(source);
|
||||
alSourcePlay(source[0]);
|
||||
// printf("Resetting sound\n");
|
||||
}
|
||||
// printf("State - %i %08X\n",state,state);
|
||||
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
|
||||
alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed);
|
||||
|
||||
// printf("P ");
|
||||
check();
|
||||
|
|
@ -157,7 +174,7 @@ void givealbuffer(int16_t *buf)
|
|||
{
|
||||
ALuint buffer;
|
||||
|
||||
alSourceUnqueueBuffers(source, 1, &buffer);
|
||||
alSourceUnqueueBuffers(source[0], 1, &buffer);
|
||||
// printf("U ");
|
||||
check();
|
||||
|
||||
|
|
@ -166,7 +183,62 @@ void givealbuffer(int16_t *buf)
|
|||
// printf("B ");
|
||||
check();
|
||||
|
||||
alSourceQueueBuffers(source, 1, &buffer);
|
||||
alSourceQueueBuffers(source[0], 1, &buffer);
|
||||
// printf("Q ");
|
||||
check();
|
||||
|
||||
// printf("\n");
|
||||
|
||||
// if (!allog) allog=fopen("al.pcm","wb");
|
||||
// fwrite(buf,BUFLEN*2,1,allog);
|
||||
}
|
||||
// printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void givealbuffer_cd(int16_t *buf)
|
||||
{
|
||||
#ifdef USE_OPENAL
|
||||
int processed;
|
||||
int state;
|
||||
|
||||
//return;
|
||||
|
||||
// printf("Start\n");
|
||||
check();
|
||||
|
||||
// printf("GiveALBuffer %08X\n",source);
|
||||
|
||||
alGetSourcei(source[1], AL_SOURCE_STATE, &state);
|
||||
|
||||
check();
|
||||
|
||||
if (state==0x1014)
|
||||
{
|
||||
alSourcePlay(source[1]);
|
||||
// printf("Resetting sound\n");
|
||||
}
|
||||
// printf("State - %i %08X\n",state,state);
|
||||
alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed);
|
||||
|
||||
// printf("P ");
|
||||
check();
|
||||
// printf("Processed - %i\n",processed);
|
||||
|
||||
if (processed>=1)
|
||||
{
|
||||
ALuint buffer;
|
||||
|
||||
alSourceUnqueueBuffers(source[1], 1, &buffer);
|
||||
// printf("U ");
|
||||
check();
|
||||
|
||||
// for (c=0;c<BUFLEN*2;c++) buf[c]^=0x8000;
|
||||
alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*2, CD_FREQ);
|
||||
// printf("B ");
|
||||
check();
|
||||
|
||||
alSourceQueueBuffers(source[1], 1, &buffer);
|
||||
// printf("Q ");
|
||||
check();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue