From 6ad19a7716da26106ba2ee3be373f0a0f39990bb Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sat, 6 Feb 2021 16:51:55 +0000 Subject: [PATCH] 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. --- bochs/config.cc | 19 ++++---- bochs/gui/siminterface.cc | 21 -------- bochs/gui/siminterface.h | 21 -------- bochs/iodev/devices.cc | 27 +++++------ bochs/iodev/iodev.h | 7 +-- bochs/iodev/network/netmod.cc | 2 +- bochs/iodev/sound/es1370.cc | 2 + bochs/iodev/sound/sb16.cc | 2 + bochs/iodev/sound/soundlow.cc | 32 +++++++++++- bochs/iodev/sound/soundlow.h | 3 ++ bochs/iodev/sound/soundmod.cc | 91 ++++++++++++++++++++++++++++------- bochs/iodev/sound/soundmod.h | 6 ++- bochs/iodev/speaker.cc | 2 + bochs/main.cc | 6 +++ 14 files changed, 151 insertions(+), 90 deletions(-) diff --git a/bochs/config.cc b/bochs/config.cc index 3d58b0d32..66f3d2560 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -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 @@ -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", diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index f715efb9b..954c5e311 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -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; diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 658e6d6e5..61116dd86 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -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. diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index 4e4d4b1bc..764e494a5 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -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; - } - return 0; + sound_device_count++; +} + +void bx_devices_c::remove_sound_device(void) +{ + sound_device_count--; } bool bx_devices_c::is_usb_enabled(void) diff --git a/bochs/iodev/iodev.h b/bochs/iodev/iodev.h index adf8b170a..382c44b67 100644 --- a/bochs/iodev/iodev.h +++ b/bochs/iodev/iodev.h @@ -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; - bool usb_enabled; + Bit8u sound_device_count; + bool usb_enabled; bool is_harddrv_enabled(); - bool is_sound_enabled(); bool is_usb_enabled(); }; diff --git a/bochs/iodev/network/netmod.cc b/bochs/iodev/network/netmod.cc index 55ba7703c..f8289ad66 100644 --- a/bochs/iodev/network/netmod.cc +++ b/bochs/iodev/network/netmod.cc @@ -154,7 +154,7 @@ eth_locator_c::eth_locator_c(const char *type) this->type = type; this->next = NULL; if (all == NULL) { - all = this; + all = this; } else { ptr = all; while (ptr->next) ptr = ptr->next; diff --git a/bochs/iodev/sound/es1370.cc b/bochs/iodev/sound/es1370.cc index fd788747f..98689df34 100644 --- a/bochs/iodev/sound/es1370.cc +++ b/bochs/iodev/sound/es1370.cc @@ -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 } diff --git a/bochs/iodev/sound/sb16.cc b/bochs/iodev/sound/sb16.cc index e5e85a0b1..3e24f2dfa 100644 --- a/bochs/iodev/sound/sb16.cc +++ b/bochs/iodev/sound/sb16.cc @@ -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 } diff --git a/bochs/iodev/sound/soundlow.cc b/bochs/iodev/sound/soundlow.cc index fa7dbcac4..481257997 100644 --- a/bochs/iodev/sound/soundlow.cc +++ b/bochs/iodev/sound/soundlow.cc @@ -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; diff --git a/bochs/iodev/sound/soundlow.h b/bochs/iodev/sound/soundlow.h index 7cdba516a..9b85579bb 100644 --- a/bochs/iodev/sound/soundlow.h +++ b/bochs/iodev/sound/soundlow.h @@ -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; diff --git a/bochs/iodev/sound/soundmod.cc b/bochs/iodev/sound/soundmod.cc index b6f854dda..675ff65ed 100644 --- a/bochs/iodev/sound/soundmod.cc +++ b/bochs/iodev/sound/soundmod.cc @@ -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(); } diff --git a/bochs/iodev/sound/soundmod.h b/bochs/iodev/sound/soundmod.h index 80110b251..989285ea6 100644 --- a/bochs/iodev/sound/soundmod.h +++ b/bochs/iodev/sound/soundmod.h @@ -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; diff --git a/bochs/iodev/speaker.cc b/bochs/iodev/speaker.cc index b7bcd2599..c6d8fcb34 100644 --- a/bochs/iodev/speaker.cc +++ b/bochs/iodev/speaker.cc @@ -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 } diff --git a/bochs/main.cc b/bochs/main.cc index 285616681..f43dcceb6 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -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 @@ -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()) {