Skip to content

Commit

Permalink
Introduce sound input infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
Cacodemon345 committed Jan 18, 2024
1 parent 19af46a commit 0b56dac
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/86box.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ int isartc_type = 0; /* (C) enable
int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
char sound_input_dev_name[512] = { 0 }; /* (C) Name of sound input device */
int sound_input_enabled = 0; /* (C) Receive sound input */
int voodoo_enabled = 0; /* (C) video option */
int ibm8514_standalone_enabled = 0; /* (C) video option */
int xga_standalone_enabled = 0; /* (C) video option */
Expand Down
18 changes: 18 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,14 @@ load_sound(void)
} else {
fm_driver = FM_DRV_NUKED;
}

memset(temp, '\0', sizeof(temp));
memset(sound_input_dev_name, '\0', sizeof(sound_input_dev_name));
p = ini_section_get_string(cat, "sound_input_dev_name", "");
strncpy(temp, p, 511);
strncpy(sound_input_dev_name, temp, 511);

sound_input_enabled = !!ini_section_get_int(cat, "sound_input_enabled", 0);
}

/* Load "Network" section. */
Expand Down Expand Up @@ -2129,6 +2137,16 @@ save_sound(void)

ini_section_set_string(cat, "fm_driver", (fm_driver == FM_DRV_NUKED) ? "nuked" : "ymfm");

if (sound_input_dev_name[0] != 0)
ini_section_set_string(cat, "sound_input_dev_name", sound_input_dev_name);
else
ini_section_delete_var(cat, "sound_input_dev_name");

if (sound_input_enabled)
ini_section_set_int(cat, "sound_input_enabled", sound_input_enabled);
else
ini_section_delete_var(cat, "sound_input_enabled");

ini_delete_section_if_empty(config, cat);
}

Expand Down
2 changes: 2 additions & 0 deletions src/include/86box/86box.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ extern int unittester_enabled; /* (C) enable unit tester device */
extern int isamem_type[]; /* (C) enable ISA mem cards */
extern int isartc_type; /* (C) enable ISA RTC card */
extern int sound_is_float; /* (C) sound uses FP values */
extern char sound_input_dev_name[512]; /* (C) Name of sound input device */
extern int sound_input_enabled; /* (C) Receive sound input */
extern int voodoo_enabled; /* (C) video option */
extern int ibm8514_standalone_enabled; /* (C) video option */
extern int xga_standalone_enabled; /* (C) video option */
Expand Down
4 changes: 3 additions & 1 deletion src/include/86box/snd_sb_dsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ typedef struct sb_dsp_t {

int record_pos_read;
int record_pos_write;
int16_t record_buffer[0xFFFF];
int record_pos_write_mic;
int16_t record_buffer[0x10000];
int16_t record_buffer_mic[0x10000];
int16_t buffer[SOUNDBUFLEN * 2];
int pos;

Expand Down
11 changes: 11 additions & 0 deletions src/include/86box/sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ extern void sound_add_handler(void (*get_buffer)(int32_t *buffer,
int len, void *priv),
void *priv);

extern void sound_in_add_handler(void (*get_buffer)(int16_t *buffer,
int len, void *priv),
void *priv);

extern void sound_in_start_input(void);
extern void sound_in_stop_input(void);

extern void sound_set_cd_audio_filter(void (*filter)(int channel,
double *buffer, void *priv),
void *priv);
Expand Down Expand Up @@ -87,6 +94,10 @@ extern void closeal(void);
extern void inital(void);
extern void givealbuffer(void *buf);
extern void givealbuffer_cd(void *buf);
extern int al_capture_available(void);
extern void al_capture_start(void);
extern void al_capture_stop(void);
extern void al_capture_get_data(int16_t* buf, size_t *len);

#define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base
extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv);
Expand Down
54 changes: 54 additions & 0 deletions src/sound/openal.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static int initialized = 0;
static int sources = 2;
static ALCcontext *Context;
static ALCdevice *Device;
static ALCdevice *CaptureDevice;

void
al_set_midi(int freq, int buf_size)
Expand All @@ -69,13 +70,22 @@ alutInit(UNUSED(ALint *argc), UNUSED(ALbyte **argv))
if (Context != NULL) {
/* Set active context */
alcMakeContextCurrent(Context);
alcProcessContext(Context);
}
}
/* Open capture device. */
CaptureDevice = NULL;
if (sound_input_enabled)
CaptureDevice = alcCaptureOpenDevice(sound_input_dev_name[0] ? (ALCchar *)sound_input_dev_name : NULL, 48000, AL_FORMAT_MONO16, SOUNDBUFLEN);
}

ALvoid
alutExit(ALvoid)
{
if (CaptureDevice) {
alcCaptureCloseDevice(CaptureDevice);
CaptureDevice = NULL;
}
if (Context != NULL) {
/* Disable context */
alcMakeContextCurrent(NULL);
Expand Down Expand Up @@ -109,6 +119,50 @@ closeal(void)
initialized = 0;
}

int
al_capture_available(void)
{
return !!CaptureDevice;
}

void
al_capture_start(void)
{
if (al_capture_available()) {
alcCaptureStart(CaptureDevice);
}
}

void
al_capture_stop(void)
{
if (al_capture_available()) {
alcCaptureStop(CaptureDevice);
}
}

void
al_capture_get_data(int16_t* buf, size_t *len)
{
if (!buf)
return;

if (*len > SOUNDBUFLEN)
*len = SOUNDBUFLEN;

if (al_capture_available()) {
ALint availableSamples = 0;

alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &availableSamples);
if (availableSamples > 0) {
if (availableSamples > SOUNDBUFLEN)
availableSamples = SOUNDBUFLEN;
*len = availableSamples;
alcCaptureSamples(CaptureDevice, buf, availableSamples);
}
}
}

void
inital(void)
{
Expand Down
57 changes: 55 additions & 2 deletions src/sound/snd_sb.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,54 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv)
*buffer = c * master;
}

#define CLAMP(x) (((x) < -32768) ? 0 : ((x > 32767) ? 32767 : 0))

/* Unused for now. */
__attribute__((unused))
static void
sb_put_buffer_sb16_awe32(int16_t *buffer, int len, void *priv)
{
sb_t *sb = (sb_t *) priv;
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
int dsp_rec_pos = sb->dsp.record_pos_write_mic;
int c_record;
int32_t in_l;
int32_t in_r;

for (int c = 0; c < len; c++) {
in_l = (mixer->input_selector_left & INPUT_MIC) ? ((int32_t) buffer[c]) : 0;
in_r = (mixer->input_selector_right & INPUT_MIC) ? ((int32_t) buffer[c]) : 0;

if (sb->dsp.sb_enable_i) {
c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / SOUND_FREQ);
in_l <<= mixer->input_gain_L;
in_r <<= mixer->input_gain_R;

/* Clip signal */
if (in_l < -32768)
in_l = -32768;
else if (in_l > 32767)
in_l = 32767;

if (in_r < -32768)
in_r = -32768;
else if (in_r > 32767)
in_r = 32767;

if (sb->dsp.record_pos_write_mic <= sb->dsp.record_pos_write) {
sb->dsp.record_buffer[c_record & 0xffff] = CLAMP((int32_t)sb->dsp.record_buffer[c_record & 0xffff] + (int32_t)in_l);
sb->dsp.record_buffer[(c_record + 1) & 0xffff] = CLAMP((int32_t)sb->dsp.record_buffer[(c_record + 1) & 0xffff] + (int32_t)in_r);;
} else {
sb->dsp.record_buffer[c_record & 0xffff] = in_l;
sb->dsp.record_buffer[(c_record + 1) & 0xffff] = in_r;
}
}
}

sb->dsp.record_pos_write_mic += ((len * sb->dsp.sb_freq) / 24000);
sb->dsp.record_pos_write_mic &= 0xffff;
}

static void
sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
{
Expand Down Expand Up @@ -456,8 +504,13 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
else if (in_r > 32767)
in_r = 32767;

sb->dsp.record_buffer[c_record & 0xffff] = in_l;
sb->dsp.record_buffer[(c_record + 1) & 0xffff] = in_r;
if (sb->dsp.record_pos_write_mic > sb->dsp.record_pos_write) {
sb->dsp.record_buffer[c_record & 0xffff] = CLAMP((int32_t)sb->dsp.record_buffer[c_record & 0xffff] + (int32_t)in_l);
sb->dsp.record_buffer[(c_record + 1) & 0xffff] = CLAMP((int32_t)sb->dsp.record_buffer[(c_record + 1) & 0xffff] + (int32_t)in_r);
} else {
sb->dsp.record_buffer[c_record & 0xffff] = in_l;
sb->dsp.record_buffer[(c_record + 1) & 0xffff] = in_r;
}
}

buffer[c] += (int32_t) (out_l * mixer->output_gain_L);
Expand Down
49 changes: 49 additions & 0 deletions src/sound/sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,17 @@ typedef struct {
void *priv;
} sound_handler_t;

typedef struct {
void (*put_buffer)(int16_t *buffer, int len, void *priv);
void *priv;
} sound_in_handler_t;

int sound_card_current[SOUND_CARD_MAX] = { 0, 0, 0, 0 };
int sound_pos_global = 0;
int sound_gain = 0;

static sound_handler_t sound_handlers[8];
static sound_in_handler_t sound_in_handlers[8];

static thread_t *sound_cd_thread_h;
static event_t *sound_cd_event;
Expand All @@ -64,12 +70,15 @@ static int32_t *outbuffer;
static float *outbuffer_ex;
static int16_t *outbuffer_ex_int16;
static int sound_handlers_num;
static int sound_in_handlers_num;
static uint8_t sound_in_started_input;
static pc_timer_t sound_poll_timer;
static uint64_t sound_poll_latch;

static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2];
static float cd_out_buffer[CD_BUFLEN * 2];
static int16_t cd_out_buffer_int16[CD_BUFLEN * 2];
static int16_t sound_input_buffer[SOUNDBUFLEN];
static unsigned int cd_vol_l;
static unsigned int cd_vol_r;
static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN;
Expand Down Expand Up @@ -438,6 +447,14 @@ sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void
sound_handlers_num++;
}

void
sound_in_add_handler(void (*put_buffer)(int16_t *buffer, int len, void *priv), void *priv)
{
sound_in_handlers[sound_handlers_num].put_buffer = put_buffer;
sound_in_handlers[sound_handlers_num].priv = priv;
sound_in_handlers_num++;
}

void
sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv)
{
Expand Down Expand Up @@ -471,6 +488,15 @@ sound_poll(UNUSED(void *priv))

for (c = 0; c < sound_handlers_num; c++)
sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv);

if (sound_in_started_input) {
size_t len = 0;
al_capture_get_data(sound_input_buffer, &len);
if (len) {
for (c = 0; c < sound_in_handlers_num; c++)
sound_in_handlers[c].put_buffer(sound_input_buffer, (int)len, sound_in_handlers[c].priv);
}
}

for (c = 0; c < SOUNDBUFLEN * 2; c++) {
if (sound_is_float)
Expand Down Expand Up @@ -508,6 +534,27 @@ sound_speed_changed(void)
sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ));
}

void
sound_in_start_input(void)
{
uint8_t old = sound_in_started_input;
sound_in_started_input++;
if (!old && sound_in_started_input && al_capture_available()) {
al_capture_start();
}
}

void
sound_in_stop_input(void)
{
uint8_t old = sound_in_started_input;
if (sound_in_started_input)
sound_in_started_input--;
if (old && !sound_in_started_input && al_capture_available()) {
al_capture_stop();
}
}

void
sound_reset(void)
{
Expand All @@ -522,6 +569,8 @@ sound_reset(void)

sound_handlers_num = 0;
memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t));
sound_in_handlers_num = 0;
memset(sound_handlers, 0x00, 8 * sizeof(sound_in_handler_t));

filter_cd_audio = NULL;
filter_cd_audio_p = NULL;
Expand Down
24 changes: 24 additions & 0 deletions src/sound/xaudio2.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,27 @@ givealbuffer_midi(void *buf, uint32_t size)
{
givealbuffer_common(buf, srcvoicemidi, size);
}

int
al_capture_available(void)
{
return 0;
}

void
al_capture_start(void)
{

}

void
al_capture_stop(void)
{

}

void
al_capture_get_data(int16_t* buf, size_t *len)
{

}

0 comments on commit 0b56dac

Please sign in to comment.