Sound runtime options support completed

- SB16: log file name now also available as a runtime option
- SB16: changed order of the runtime options and minor other changes
- ES1370: changed the "wavemode" parameter type to bx_param_enum_c and set up
  more accurate dependencies (similar to SB16)
- ES1370: wave mode and file name now available as a runtime option
This commit is contained in:
Volker Ruppert 2013-11-28 20:47:34 +00:00
parent 0be25b75fe
commit 3a22a7de61
4 changed files with 162 additions and 41 deletions

View File

@ -92,6 +92,14 @@ const Bit16u sctl_loop_sel[3] = {0x2000, 0x4000, 0x8000};
void es1370_init_options(void)
{
static const char *es1370_wavemode_list[] = {
"0",
"1",
"2",
"3",
NULL
};
bx_param_c *sound = SIM->get_param("sound");
bx_list_c *menu = new bx_list_c(sound, "es1370", "ES1370 Configuration");
menu->set_options(menu->SHOW_PARENT);
@ -104,12 +112,12 @@ void es1370_init_options(void)
0);
enabled->set_enabled(BX_SUPPORT_ES1370);
bx_param_num_c *wavemode = new bx_param_num_c(menu,
bx_param_enum_c *wavemode = new bx_param_enum_c(menu,
"wavemode",
"Wave mode",
"Controls the wave output format.",
0, 3,
0);
es1370_wavemode_list,
0, 0);
bx_param_filename_c *wavefile = new bx_param_filename_c(menu,
"wavefile",
"Wave file",
@ -117,8 +125,12 @@ void es1370_init_options(void)
"", BX_PATHNAME_LEN);
bx_list_c *deplist = new bx_list_c(NULL);
deplist->add(wavemode);
deplist->add(wavefile);
enabled->set_dependent_list(deplist);
deplist = new bx_list_c(NULL);
deplist->add(wavefile);
wavemode->set_dependent_list(deplist, 0);
wavemode->set_dependent_bitmap(2, 0x1);
wavemode->set_dependent_bitmap(3, 0x1);
}
Bit32s es1370_options_parser(const char *context, int num_params, char *params[])
@ -181,14 +193,11 @@ bx_es1370_c::~bx_es1370_c()
if (s.adc_inputinit) {
soundmod->closewaveinput();
}
if (BX_ES1370_THIS wavemode == 2) {
fputc(0, BX_ES1370_THIS wavefile);
}
if (wavefile != NULL) {
fclose(wavefile);
}
closewaveoutput();
SIM->get_bochs_root()->remove("es1370");
bx_list_c *misc_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_MISC);
misc_rt->remove("es1370");
BX_DEBUG(("Exit"));
}
@ -217,18 +226,7 @@ void bx_es1370_c::init(void)
BX_ES1370_THIS s.adc_inputinit = 0;
BX_ES1370_THIS s.dac_nr_active = -1;
BX_ES1370_THIS wavemode = SIM->get_param_num("wavemode", base)->get();
if ((BX_ES1370_THIS wavemode == 2) || (BX_ES1370_THIS wavemode == 3)) {
BX_ES1370_THIS wavefile = fopen(SIM->get_param_string("wavefile", base)->getptr(), "wb");
if (BX_ES1370_THIS wavefile == NULL) {
BX_ERROR(("Error opening file '%s' - wave output disabled",
SIM->get_param_string("wavefile", base)->getptr()));
BX_ES1370_THIS wavemode = 0;
}
if ((BX_ES1370_THIS wavemode == 2) && (BX_ES1370_THIS wavefile != NULL)) {
DEV_soundmod_VOC_init_file(BX_ES1370_THIS wavefile);
}
}
BX_ES1370_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
if (BX_ES1370_THIS s.dac1_timer_index == BX_NULL_TIMER_HANDLE) {
BX_ES1370_THIS s.dac1_timer_index = bx_pc_system.register_timer
@ -241,6 +239,19 @@ void bx_es1370_c::init(void)
// DAC2 timer: inactive, continuous, frequency variable
}
// init runtime parameters
bx_list_c *misc_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_MISC);
bx_list_c *menu = new bx_list_c(misc_rt, "es1370", "ES1370 Runtime Options");
menu->set_options(menu->SHOW_PARENT | menu->USE_BOX_TITLE);
menu->add(SIM->get_param("wavemode", base));
menu->add(SIM->get_param("wavefile", base));
SIM->get_param_enum("wavemode", base)->set_handler(es1370_param_handler);
SIM->get_param_string("wavefile", base)->set_handler(es1370_param_string_handler);
// register handler for correct es1370 parameter handling after runtime config
SIM->register_runtime_config_handler(this, runtime_config_handler);
BX_ES1370_THIS wave_changed = 0;
BX_INFO(("ES1370 initialized"));
}
@ -330,6 +341,23 @@ void bx_es1370_c::after_restore_state(void)
BX_ES1370_THIS update_voices(BX_ES1370_THIS s.ctl, BX_ES1370_THIS s.sctl, 1);
}
void bx_es1370_c::runtime_config_handler(void *this_ptr)
{
bx_es1370_c *class_ptr = (bx_es1370_c *) this_ptr;
class_ptr->runtime_config();
}
void bx_es1370_c::runtime_config(void)
{
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370);
if (BX_ES1370_THIS wave_changed) {
BX_ES1370_THIS closewaveoutput();
BX_ES1370_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
// update_voices() re-opens the output file on demand
BX_ES1370_THIS wave_changed = 0;
}
}
// static IO port read callback handler
// redirects to non-static class handler to avoid virtual functions
@ -712,6 +740,21 @@ void bx_es1370_c::update_voices(Bit32u ctl, Bit32u sctl, bx_bool force)
} else {
BX_ES1370_THIS s.dac_nr_active = i;
}
} else if ((BX_ES1370_THIS wavemode == 2) ||
(BX_ES1370_THIS wavemode == 3)) {
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370);
bx_param_string_c *waveparam = SIM->get_param_string("wavefile", base);
if ((BX_ES1370_THIS wavefile == NULL) && (!waveparam->isempty())) {
BX_ES1370_THIS wavefile = fopen(waveparam->getptr(), "wb");
if (BX_ES1370_THIS wavefile == NULL) {
BX_ERROR(("Error opening file '%s' - wave output disabled",
waveparam->getptr()));
BX_ES1370_THIS wavemode = 0;
} else if (BX_ES1370_THIS wavemode == 2) {
DEV_soundmod_VOC_init_file(BX_ES1370_THIS wavefile);
}
}
BX_ES1370_THIS s.dac_nr_active = i;
} else {
BX_ES1370_THIS s.dac_nr_active = i;
}
@ -777,6 +820,24 @@ void bx_es1370_c::sendwavepacket(unsigned channel, Bit32u buflen, Bit8u *buffer)
}
}
void bx_es1370_c::closewaveoutput()
{
switch (BX_ES1370_THIS wavemode) {
case 1:
// nothing to do here yet
break;
case 2:
if (BX_ES1370_THIS wavefile != NULL) {
fputc(0, BX_ES1370_THIS wavefile);
}
case 3:
if (BX_ES1370_THIS wavefile != NULL)
fclose(BX_ES1370_THIS wavefile);
BX_ES1370_THIS wavefile = NULL;
break;
}
}
// pci configuration space read callback handler
Bit32u bx_es1370_c::pci_read_handler(Bit8u address, unsigned io_len)
{
@ -854,4 +915,35 @@ void bx_es1370_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len
BX_DEBUG(("write PCI register 0x%02x value 0x%08x", address, value));
}
// runtime parameter handlers
Bit64s bx_es1370_c::es1370_param_handler(bx_param_c *param, int set, Bit64s val)
{
if (set) {
const char *pname = param->get_name();
if (!strcmp(pname, "wavemode")) {
if (val != BX_ES1370_THIS wavemode) {
BX_ES1370_THIS wave_changed = 1;
}
} else {
BX_PANIC(("es1370_param_handler called with unexpected parameter '%s'", pname));
}
}
return val;
}
const char* bx_es1370_c::es1370_param_string_handler(bx_param_string_c *param, int set,
const char *oldval, const char *val,
int maxlen)
{
if ((set) && (strcmp(val, oldval))) {
const char *pname = param->get_name();
if (!strcmp(pname, "wave")) {
BX_ES1370_THIS wave_changed = 1;
} else {
BX_PANIC(("es1370_param_string_handler called with unexpected parameter '%s'", pname));
}
}
return val;
}
#endif // BX_SUPPORT_PCI && BX_SUPPORT_ES1370

View File

@ -81,6 +81,14 @@ public:
virtual Bit32u pci_read_handler(Bit8u address, unsigned io_len);
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
// runtime options
static Bit64s es1370_param_handler(bx_param_c *param, int set, Bit64s val);
static const char* es1370_param_string_handler(bx_param_string_c *param, int set,
const char *oldval, const char *val,
int maxlen);
static void runtime_config_handler(void *);
void runtime_config(void);
private:
bx_es1370_t s;
@ -90,6 +98,7 @@ private:
BX_ES1370_SMF void update_voices(Bit32u ctl, Bit32u sctl, bx_bool force);
BX_ES1370_SMF void run_channel(unsigned channel, int timer_id, Bit32u buflen);
BX_ES1370_SMF void sendwavepacket(unsigned channel, Bit32u buflen, Bit8u *buffer);
BX_ES1370_SMF void closewaveoutput();
static void es1370_timer_handler(void *);
void es1370_timer(void);
@ -105,6 +114,7 @@ private:
bx_sound_lowlevel_c *soundmod;
int wavemode;
bx_bool wave_changed;
FILE *wavefile;
};

View File

@ -216,7 +216,7 @@ bx_sb16_c::~bx_sb16_c(void)
delete [] DSP.dma.chunk;
if ((loglevel > 0) && (LOGFILE != NULL))
if (LOGFILE != NULL)
fclose(LOGFILE);
SIM->get_bochs_root()->remove("sb16");
@ -238,18 +238,7 @@ void bx_sb16_c::init(void)
((bx_param_bool_c*)((bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL))->get_by_name("sb16"))->set(0);
return;
}
if ((strlen(SIM->get_param_string("log", base)->getptr()) < 1))
SIM->get_param_num("loglevel", base)->set(0);
if (SIM->get_param_num("loglevel", base)->get() > 0)
{
LOGFILE = fopen(SIM->get_param_string("log", base)->getptr(),"w"); // logfile for errors etc.
if (LOGFILE == NULL)
{
BX_ERROR(("Error opening file %s. Logging disabled.", SIM->get_param_string("log", base)->getptr()));
SIM->get_param_num("loglevel", base)->set(0);
}
}
create_logfile();
BX_SB16_THIS midimode = SIM->get_param_num("midimode", base)->get();
BX_SB16_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
BX_SB16_THIS dmatimer = SIM->get_param_num("dmatimer", base)->get();
@ -384,18 +373,20 @@ void bx_sb16_c::init(void)
bx_list_c *menu = new bx_list_c(misc_rt, "sb16", "SB16 Runtime Options");
menu->set_options(menu->SHOW_PARENT | menu->USE_BOX_TITLE);
menu->add(SIM->get_param("wavemode", base));
menu->add(SIM->get_param("wave", base));
menu->add(SIM->get_param("midimode", base));
menu->add(SIM->get_param("midi", base));
menu->add(SIM->get_param("dmatimer", base));
menu->add(SIM->get_param("wavemode", base));
menu->add(SIM->get_param("wave", base));
menu->add(SIM->get_param("loglevel", base));
menu->add(SIM->get_param("log", base));
menu->add(SIM->get_param("dmatimer", base));
SIM->get_param_enum("wavemode", base)->set_handler(sb16_param_handler);
SIM->get_param_string("wave", base)->set_handler(sb16_param_string_handler);
SIM->get_param_num("midimode", base)->set_handler(sb16_param_handler);
SIM->get_param_string("midi", base)->set_handler(sb16_param_string_handler);
SIM->get_param_num("dmatimer", base)->set_handler(sb16_param_handler);
SIM->get_param_num("loglevel", base)->set_handler(sb16_param_handler);
SIM->get_param_string("log", base)->set_handler(sb16_param_string_handler);
// register handler for correct sb16 parameter handling after runtime config
SIM->register_runtime_config_handler(this, runtime_config_handler);
BX_SB16_THIS midi_changed = 0;
@ -556,7 +547,7 @@ void bx_sb16_c::runtime_config(void)
}
if (BX_SB16_THIS wave_changed) {
BX_SB16_THIS closewaveoutput();
BX_SB16_THIS wavemode = SIM->get_param_num("wavemode", base)->get();
BX_SB16_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
// dsp_dma() re-opens the output file on demand
BX_SB16_THIS wave_changed = 0;
}
@ -3577,11 +3568,32 @@ void bx_sb16_c::write(Bit32u address, Bit32u value, unsigned io_len)
address, value);
}
void bx_sb16_c::create_logfile(void)
{
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
bx_param_string_c *logfile = SIM->get_param_string("log", base);
if (logfile->isempty()) {
SIM->get_param_num("loglevel", base)->set(0);
return;
}
if (SIM->get_param_num("loglevel", base)->get() > 0) {
LOGFILE = fopen(logfile->getptr(),"w"); // logfile for errors etc.
if (LOGFILE == NULL) {
BX_ERROR(("Error opening file %s. Logging disabled.", logfile->getptr()));
SIM->get_param_num("loglevel", base)->set(0);
}
}
}
void bx_sb16_c::writelog(int loglev, const char *str, ...)
{
if ((LOGFILE == NULL) && (BX_SB16_THIS loglevel != 0)) {
create_logfile();
}
// append a line to the log file, if desired
if (BX_SB16_THIS loglevel >= loglev)
{
if (BX_SB16_THIS loglevel >= loglev) {
fprintf(LOGFILE, FMT_TICK, bx_pc_system.time_ticks());
fprintf(LOGFILE, " (%d) ", loglev);
va_list ap;
@ -3863,6 +3875,12 @@ const char* bx_sb16_c::sb16_param_string_handler(bx_param_string_c *param, int s
BX_SB16_THIS wave_changed = 1;
} else if (!strcmp(pname, "midi")) {
BX_SB16_THIS midi_changed = 1;
} else if (!strcmp(pname, "log")) {
if (LOGFILE != NULL) {
fclose(LOGFILE);
LOGFILE = NULL;
}
// writelog() re-opens the log file on demand
} else {
BX_PANIC(("sb16_param_string_handler called with unexpected parameter '%s'", pname));
}

View File

@ -364,6 +364,7 @@ private:
BX_SB16_SMF void closewaveoutput(); // close wave file
BX_SB16_SMF void finishmidifile(); // write track length etc.
BX_SB16_SMF void finishvocfile(); // close voc file
BX_SB16_SMF void create_logfile();
/* The port IO multiplexer functions */