Rewrite of the sound driver handling similar to the hdimage and networking

module code. Sound driver names are now stored as string constants instead
of hardcoded values. Available modules are detected at Bochs startup and stored
in a string array before initializing options. In the plugins case available
modules are read from the plugins list. If plugins are off, the registry of
bx_sound_lowlevel_c is used. Related changes similar to the hdimage and
network modifications.
This commit is contained in:
Volker Ruppert 2021-02-06 16:51:55 +00:00
parent 30b9c1b086
commit 6ad19a7716
14 changed files with 151 additions and 90 deletions

View File

@ -25,6 +25,9 @@
#if BX_NETWORKING
#include "iodev/network/netmod.h"
#endif
#if BX_SUPPORT_SOUNDLOW
#include "iodev/sound/soundmod.h"
#endif
#include "param_names.h"
#include <assert.h>
@ -1526,13 +1529,13 @@ void bx_init_options()
soundlow->set_enabled(BX_SUPPORT_SOUNDLOW);
#if BX_SUPPORT_SOUNDLOW
bx_soundmod_ctl.init();
bx_param_enum_c *driver = new bx_param_enum_c(soundlow,
"waveoutdrv",
"Waveout driver",
"This is the waveout driver to use for emulated sound devices",
sound_driver_names,
BX_SOUNDDRV_DUMMY,
BX_SOUNDDRV_DUMMY);
bx_soundmod_ctl.get_driver_names(),
0, 0);
driver->set_by_name(BX_SOUND_LOWLEVEL_NAME);
new bx_param_filename_c(soundlow,
"waveout",
@ -1543,9 +1546,8 @@ void bx_init_options()
"waveindrv",
"Wavein driver",
"This is the wavein driver to use for emulated sound devices",
sound_driver_names,
BX_SOUNDDRV_DUMMY,
BX_SOUNDDRV_DUMMY);
bx_soundmod_ctl.get_driver_names(),
0, 0);
driver->set_by_name(BX_SOUND_LOWLEVEL_NAME);
new bx_param_filename_c(soundlow,
"wavein",
@ -1556,9 +1558,8 @@ void bx_init_options()
"midioutdrv",
"Midiout driver",
"This is the midiout driver to use for emulated sound devices",
sound_driver_names,
BX_SOUNDDRV_DUMMY,
BX_SOUNDDRV_DUMMY);
bx_soundmod_ctl.get_driver_names(),
0, 0);
driver->set_by_name(BX_SOUND_LOWLEVEL_NAME);
new bx_param_filename_c(soundlow,
"midiout",

View File

@ -521,27 +521,6 @@ int floppy_type_n_sectors[] = { -1, 80*2*15, 80*2*18, 80*2*36, 80*2*9, 40*2*9, 4
const char *media_status_names[] = { "ejected", "inserted", NULL };
const char *bochs_bootdisk_names[] = { "none", "floppy", "disk","cdrom", "network", NULL };
const char *sound_driver_names[] = {
"dummy",
#if BX_HAVE_SOUND_ALSA
"alsa",
#endif
#if BX_HAVE_SOUND_OSS
"oss",
#endif
#if BX_HAVE_SOUND_OSX
"osx",
#endif
#if BX_HAVE_SOUND_SDL
"sdl",
#endif
#if BX_HAVE_SOUND_WIN
"win",
#endif
"file",
NULL
};
void bx_real_sim_c::set_notify_callback(bxevent_handler func, void *arg)
{
bxevent_callback = func;

View File

@ -572,32 +572,11 @@ enum {
#define BX_CLOCK_TIME0_LOCAL 1
#define BX_CLOCK_TIME0_UTC 2
enum {
BX_SOUNDDRV_DUMMY,
#if BX_HAVE_SOUND_ALSA
BX_SOUNDDRV_ALSA,
#endif
#if BX_HAVE_SOUND_OSS
BX_SOUNDDRV_OSS,
#endif
#if BX_HAVE_SOUND_OSX
BX_SOUNDDRV_OSX,
#endif
#if BX_HAVE_SOUND_SDL
BX_SOUNDDRV_SDL,
#endif
#if BX_HAVE_SOUND_WIN
BX_SOUNDDRV_WIN,
#endif
BX_SOUNDDRV_FILE
};
BOCHSAPI extern const char *floppy_devtype_names[];
BOCHSAPI extern const char *floppy_type_names[];
BOCHSAPI extern int floppy_type_n_sectors[];
BOCHSAPI extern const char *media_status_names[];
BOCHSAPI extern const char *bochs_bootdisk_names[];
BOCHSAPI extern const char *sound_driver_names[];
////////////////////////////////////////////////////////////////////
// base class simulator interface, contains just virtual functions.

View File

@ -61,6 +61,7 @@ bx_devices_c::bx_devices_c()
for (unsigned i=0; i < BX_MAX_IRQS; i++) {
irq_handler_name[i] = NULL;
}
sound_device_count = 0;
}
bx_devices_c::~bx_devices_c()
@ -70,6 +71,9 @@ bx_devices_c::~bx_devices_c()
#if BX_NETWORKING
bx_netmod_ctl.exit();
#endif
#if BX_SUPPORT_SOUNDLOW
bx_soundmod_ctl.exit();
#endif
}
void bx_devices_c::init_stubs()
@ -175,9 +179,8 @@ void bx_devices_c::init(BX_MEM_C *newmem)
bx_slowdown_timer.init();
#if BX_SUPPORT_SOUNDLOW
sound_enabled = is_sound_enabled();
if (sound_enabled) {
bx_soundmod_ctl.init();
if (sound_device_count > 0) {
bx_soundmod_ctl.open_output();
}
#endif
// PCI logic (i440FX)
@ -449,10 +452,6 @@ void bx_devices_c::exit()
// unload optional plugins first
bx_unload_plugins();
bx_unload_core_plugins();
#if BX_SUPPORT_SOUNDLOW
if (sound_enabled)
bx_soundmod_ctl.exit();
#endif
#if BX_SUPPORT_PCIUSB
if (usb_enabled)
bx_usbdev_ctl.exit();
@ -1115,14 +1114,14 @@ bool bx_devices_c::is_harddrv_enabled(void)
return 0;
}
bool bx_devices_c::is_sound_enabled(void)
void bx_devices_c::add_sound_device(void)
{
if (PLUG_device_present("es1370") ||
PLUG_device_present("sb16") ||
PLUG_device_present("speaker")) {
return 1;
sound_device_count++;
}
return 0;
void bx_devices_c::remove_sound_device(void)
{
sound_device_count--;
}
bool bx_devices_c::is_usb_enabled(void)

View File

@ -429,6 +429,8 @@ public:
void kbd_set_indicator(Bit8u devid, Bit8u ledid, bool state);
void mouse_enabled_changed(bool enabled);
void mouse_motion(int delta_x, int delta_y, int delta_z, unsigned button_state, bool absxy);
void add_sound_device(void);
void remove_sound_device(void);
#if BX_SUPPORT_PCI
Bit32u pci_get_confAddr(void) {return pci.confAddr;}
@ -602,11 +604,10 @@ private:
int timer_handle;
int statusbar_id[3];
bool sound_enabled;
Bit8u sound_device_count;
bool usb_enabled;
bool is_harddrv_enabled();
bool is_sound_enabled();
bool is_usb_enabled();
};

View File

@ -196,11 +196,13 @@ PLUGIN_ENTRY_FOR_MODULE(es1370)
es1370_init_options();
// register add-on option for bochsrc and command line
SIM->register_addon_option("es1370", es1370_options_parser, es1370_options_save);
bx_devices.add_sound_device();
} else {
delete theES1370Device;
SIM->unregister_addon_option("es1370");
bx_list_c *menu = (bx_list_c*)SIM->get_param("sound");
menu->remove("es1370");
bx_devices.remove_sound_device();
}
return 0; // Success
}

View File

@ -172,10 +172,12 @@ PLUGIN_ENTRY_FOR_MODULE(sb16)
sb16_init_options();
// register add-on option for bochsrc and command line
SIM->register_addon_option("sb16", sb16_options_parser, sb16_options_save);
bx_devices.add_sound_device();
} else {
delete theSB16Device;
SIM->unregister_addon_option("sb16");
((bx_list_c*)SIM->get_param("sound"))->remove("sb16");
bx_devices.remove_sound_device();
}
return(0); // Success
}

View File

@ -595,20 +595,30 @@ int bx_soundlow_midiout_c::closemidioutput()
return BX_SOUNDLOW_OK;
}
Bit8u bx_sound_lowlevel_c::count = 0;
bx_sound_lowlevel_c *bx_sound_lowlevel_c::all;
// bx_sound_lowlevel_c class implementation
bx_sound_lowlevel_c::bx_sound_lowlevel_c(const char *type)
{
bx_sound_lowlevel_c *ptr;
put("soundlow", "SNDLOW");
waveout = NULL;
wavein = NULL;
midiout = NULL;
// self-registering static objects ported from the network code
next = all;
all = this;
this->type = type;
this->next = NULL;
if (all == NULL) {
all = this;
} else {
ptr = all;
while (ptr->next) ptr = ptr->next;
ptr->next = this;
}
count++;
}
bx_sound_lowlevel_c::~bx_sound_lowlevel_c()
@ -642,6 +652,24 @@ bx_sound_lowlevel_c::~bx_sound_lowlevel_c()
}
}
Bit8u bx_sound_lowlevel_c::get_modules_count()
{
return count;
}
const char* bx_sound_lowlevel_c::get_module_name(Bit8u index)
{
bx_sound_lowlevel_c *ptr;
Bit8u n = 0;
for (ptr = all; ptr != NULL; ptr = ptr->next) {
if (n == index)
return ptr->type;
n++;
}
return NULL;
}
bool bx_sound_lowlevel_c::module_present(const char *type)
{
bx_sound_lowlevel_c *ptr = 0;

View File

@ -174,6 +174,8 @@ public:
class BOCHSAPI_MSVCONLY bx_sound_lowlevel_c : public logfunctions {
public:
static bool module_present(const char *type);
static Bit8u get_modules_count(void);
static const char* get_module_name(Bit8u index);
static bx_sound_lowlevel_c* get_module(const char *type);
static void cleanup();
@ -189,6 +191,7 @@ protected:
bx_soundlow_wavein_c *wavein;
bx_soundlow_midiout_c *midiout;
private:
static Bit8u count;
static bx_sound_lowlevel_c *all;
bx_sound_lowlevel_c *next;
const char *type;

View File

@ -35,6 +35,7 @@
bx_soundmod_ctl_c bx_soundmod_ctl;
const char **sound_driver_names;
bx_soundmod_ctl_c::bx_soundmod_ctl_c()
{
@ -42,6 +43,71 @@ bx_soundmod_ctl_c::bx_soundmod_ctl_c()
}
void bx_soundmod_ctl_c::init()
{
Bit8u i, count = 0;
#if !BX_PLUGINS
count = bx_sound_lowlevel_c::get_modules_count();
#else
count = PLUG_get_plugins_count(PLUGTYPE_SND);
#endif
sound_driver_names = (const char**) malloc((count + 1) * sizeof(char*));
for (i = 0; i < count; i++) {
#if !BX_PLUGINS
sound_driver_names[i] = bx_sound_lowlevel_c::get_module_name(i);
#else
sound_driver_names[i] = PLUG_get_plugin_name(PLUGTYPE_SND, i);
#endif
}
sound_driver_names[count] = NULL;
// move 'dummy' module to the top of the list
if (strcmp(sound_driver_names[0], "dummy")) {
for (i = 1; i < count; i++) {
if (!strcmp(sound_driver_names[i], "dummy")) {
sound_driver_names[i] = sound_driver_names[0];
sound_driver_names[0] = "dummy";
break;
}
}
}
}
void bx_soundmod_ctl_c::exit()
{
bx_sound_lowlevel_c::cleanup();
}
const char **bx_soundmod_ctl_c::get_driver_names(void)
{
return sound_driver_names;
}
void bx_soundmod_ctl_c::list_modules(void)
{
char list[60];
Bit8u i = 0;
size_t len = 0, len1;
BX_INFO(("Sound drivers"));
list[0] = 0;
while (sound_driver_names[i] != NULL) {
len1 = strlen(sound_driver_names[i]);
if ((len + len1 + 1) > 60) {
BX_INFO((" %s", list));
list[0] = 0;
len = 0;
}
strcat(list, " ");
strcat(list, sound_driver_names[i]);
len = strlen(list);
i++;
}
if (len > 0) {
BX_INFO((" %s", list));
}
}
void bx_soundmod_ctl_c::open_output()
{
const char *pwaveout = SIM->get_param_string(BXPN_SOUND_WAVEOUT)->getptr();
const char *pwavein = SIM->get_param_string(BXPN_SOUND_WAVEIN)->getptr();
@ -61,14 +127,8 @@ void bx_soundmod_ctl_c::init()
}
}
void bx_soundmod_ctl_c::exit()
bx_sound_lowlevel_c* bx_soundmod_ctl_c::get_driver(const char *modname)
{
bx_sound_lowlevel_c::cleanup();
}
bx_sound_lowlevel_c* bx_soundmod_ctl_c::get_driver(int driver_id)
{
const char *modname = sound_driver_names[driver_id];
if (!bx_sound_lowlevel_c::module_present(modname)) {
#if BX_PLUGINS
PLUG_load_plugin_var(modname, PLUGTYPE_SND);
@ -84,10 +144,9 @@ bx_soundlow_waveout_c* bx_soundmod_ctl_c::get_waveout(bool using_file)
bx_sound_lowlevel_c *module = NULL;
if (!using_file) {
int driver_id = SIM->get_param_enum(BXPN_SOUND_WAVEOUT_DRV)->get();
module = get_driver(driver_id);
module = get_driver(SIM->get_param_enum(BXPN_SOUND_WAVEOUT_DRV)->get_selected());
} else {
module = get_driver(BX_SOUNDDRV_FILE);
module = get_driver("file");
}
if (module != NULL) {
return module->get_waveout();
@ -101,13 +160,12 @@ bx_soundlow_wavein_c* bx_soundmod_ctl_c::get_wavein()
bx_sound_lowlevel_c *module = NULL;
bx_soundlow_wavein_c *wavein = NULL;
int driver_id = SIM->get_param_enum(BXPN_SOUND_WAVEIN_DRV)->get();
module = get_driver(driver_id);
module = get_driver(SIM->get_param_enum(BXPN_SOUND_WAVEIN_DRV)->get_selected());
if (module != NULL) {
wavein = module->get_wavein();
if (wavein == NULL) {
BX_ERROR(("sound service 'wavein' not available - using dummy driver"));
module = get_driver(BX_SOUNDDRV_DUMMY);
module = get_driver("dummy");
if (module != NULL) {
wavein = module->get_wavein();
}
@ -122,16 +180,15 @@ bx_soundlow_midiout_c* bx_soundmod_ctl_c::get_midiout(bool using_file)
bx_soundlow_midiout_c *midiout = NULL;
if (!using_file) {
int driver_id = SIM->get_param_enum(BXPN_SOUND_MIDIOUT_DRV)->get();
module = get_driver(driver_id);
module = get_driver(SIM->get_param_enum(BXPN_SOUND_MIDIOUT_DRV)->get_selected());
} else {
module = get_driver(BX_SOUNDDRV_FILE);
module = get_driver("file");
}
if (module != NULL) {
midiout = module->get_midiout();
if (midiout == NULL) {
BX_ERROR(("sound service 'midiout' not available - using dummy driver"));
module = get_driver(BX_SOUNDDRV_DUMMY);
module = get_driver("dummy");
if (module != NULL) {
midiout = module->get_midiout();
}

View File

@ -32,13 +32,15 @@ public:
~bx_soundmod_ctl_c() {}
void init(void);
void exit(void);
bool register_driver(bx_sound_lowlevel_c *module, int driver_id);
const char **get_driver_names();
void list_modules(void);
void open_output(void);
bx_soundlow_waveout_c* get_waveout(bool using_file);
bx_soundlow_wavein_c* get_wavein();
bx_soundlow_midiout_c* get_midiout(bool using_file);
private:
bx_sound_lowlevel_c* get_driver(int driver_id);
bx_sound_lowlevel_c* get_driver(const char *modname);
};
BOCHSAPI extern bx_soundmod_ctl_c bx_soundmod_ctl;

View File

@ -139,11 +139,13 @@ PLUGIN_ENTRY_FOR_MODULE(speaker)
speaker_init_options();
// register add-on options for bochsrc and command line
SIM->register_addon_option("speaker", speaker_options_parser, speaker_options_save);
bx_devices.add_sound_device();
} else {
bx_devices.pluginSpeaker = &bx_devices.stubSpeaker;
delete theSpeaker;
SIM->unregister_addon_option("speaker");
((bx_list_c*)SIM->get_param("sound"))->remove("speaker");
bx_devices.remove_sound_device();
}
return(0); // Success
}

View File

@ -31,6 +31,9 @@
#if BX_NETWORKING
#include "iodev/network/netmod.h"
#endif
#if BX_SUPPORT_SOUNDLOW
#include "iodev/sound/soundmod.h"
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
@ -1299,6 +1302,9 @@ void bx_init_hardware()
bx_hdimage_ctl.list_modules();
#if BX_NETWORKING
bx_netmod_ctl.list_modules();
#endif
#if BX_SUPPORT_SOUNDLOW
bx_soundmod_ctl.list_modules();
#endif
// Check if there is a romimage
if (SIM->get_param_string(BXPN_ROM_PATH)->isempty()) {