diff --git a/bochs/iodev/sound/soundalsa.cc b/bochs/iodev/sound/soundalsa.cc index 2523f1420..ed6a07894 100644 --- a/bochs/iodev/sound/soundalsa.cc +++ b/bochs/iodev/sound/soundalsa.cc @@ -45,12 +45,6 @@ bx_sound_alsa_c::~bx_sound_alsa_c() // nothing for now } - -int bx_sound_alsa_c::waveready() -{ - return BX_SOUNDLOW_OK; -} - int bx_sound_alsa_c::midiready() { return BX_SOUNDLOW_OK; @@ -207,6 +201,8 @@ int bx_sound_alsa_c::closemidioutput() int bx_sound_alsa_c::openwaveoutput(const char *wavedev) { + real_pcm_param = default_pcm_param; + set_pcm_params(real_pcm_param); return BX_SOUNDLOW_OK; } @@ -283,9 +279,9 @@ int bx_sound_alsa_c::alsa_pcm_open(bx_bool mode, int frequency, int bits, bx_boo return BX_SOUNDLOW_OK; } -int bx_sound_alsa_c::startwaveplayback(int frequency, int bits, bx_bool stereo, int format) +int bx_sound_alsa_c::set_pcm_params(bx_pcm_param_t param) { - return alsa_pcm_open(0, frequency, bits, stereo, format); + return alsa_pcm_open(0, param.samplerate, param.bits, param.channels == 2, param.format); } int bx_sound_alsa_c::alsa_pcm_write() @@ -325,10 +321,13 @@ int bx_sound_alsa_c::sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *sr int len2; if (memcmp(src_param, &emu_pcm_param, sizeof(bx_pcm_param_t)) != 0) { - startwaveplayback(src_param->samplerate, 16, 1, 1); emu_pcm_param = *src_param; cvt_mult = (src_param->bits == 8) ? 2 : 1; if (src_param->channels == 1) cvt_mult <<= 1; + if (src_param->samplerate != real_pcm_param.samplerate) { + real_pcm_param.samplerate = src_param->samplerate; + set_pcm_params(real_pcm_param); + } } len2 = length * cvt_mult; if (!alsa_pcm[0].handle) { diff --git a/bochs/iodev/sound/soundalsa.h b/bochs/iodev/sound/soundalsa.h index 37b4110f3..ccadb5f6c 100644 --- a/bochs/iodev/sound/soundalsa.h +++ b/bochs/iodev/sound/soundalsa.h @@ -35,15 +35,13 @@ public: virtual int get_type() {return BX_SOUNDLOW_ALSA;} - virtual int waveready(); - virtual int midiready(); - virtual int openmidioutput(const char *mididev); + virtual int midiready(); virtual int sendmidicommand(int delta, int command, int length, Bit8u data[]); virtual int closemidioutput(); virtual int openwaveoutput(const char *wavedev); - virtual int startwaveplayback(int frequency, int bits, bx_bool stereo, int format); + virtual int set_pcm_params(bx_pcm_param_t param); virtual int sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *src_param); virtual int stopwaveplayback(); virtual int closewaveoutput(); diff --git a/bochs/iodev/sound/soundlnx.cc b/bochs/iodev/sound/soundlnx.cc index 5d5589054..2d0d27812 100644 --- a/bochs/iodev/sound/soundlnx.cc +++ b/bochs/iodev/sound/soundlnx.cc @@ -38,8 +38,6 @@ bx_sound_linux_c::bx_sound_linux_c() :bx_sound_lowlevel_c() { midi = NULL; - wave_device[0] = NULL; - wave_device[1] = NULL; wave_fd[0] = -1; wave_fd[1] = -1; BX_INFO(("Sound lowlevel module 'oss' initialized")); @@ -50,12 +48,6 @@ bx_sound_linux_c::~bx_sound_linux_c() // nothing for now } - -int bx_sound_linux_c::waveready() -{ - return BX_SOUNDLOW_OK; -} - int bx_sound_linux_c::midiready() { return BX_SOUNDLOW_OK; @@ -100,65 +92,51 @@ int bx_sound_linux_c::closemidioutput() int bx_sound_linux_c::openwaveoutput(const char *wavedev) { - int length = strlen(wavedev) + 1; - - if (wave_device[0] != NULL) - delete [] wave_device[0]; - - wave_device[0] = new char[length]; - - if (wave_device[0] == NULL) - return BX_SOUNDLOW_ERR; - - strncpy(wave_device[0], wavedev, length); - - return BX_SOUNDLOW_OK; -} - -int bx_sound_linux_c::startwaveplayback(int frequency, int bits, bx_bool stereo, int format) -{ - int fmt, ret; - int signeddata = format & 1; - - if ((wave_device[0] == NULL) || (strlen(wave_device[0]) < 1)) - return BX_SOUNDLOW_ERR; - if (wave_fd[0] == -1) { - wave_fd[0] = open(wave_device[0], O_WRONLY); + wave_fd[0] = open(wavedev, O_WRONLY); if (wave_fd[0] == -1) { return BX_SOUNDLOW_ERR; } else { - BX_INFO(("OSS: opened output device %s", wave_device[0])); + BX_INFO(("OSS: opened output device %s", wavedev)); + } + } + real_pcm_param = default_pcm_param; + set_pcm_params(real_pcm_param); + return BX_SOUNDLOW_OK; +} + +int bx_sound_linux_c::set_pcm_params(bx_pcm_param_t param) +{ + int fmt, ret; + int frequency = param.samplerate; + int channels = param.channels; + int signeddata = param.format & 1; + + BX_DEBUG(("set_pcm_params(): %u, %u, %u, %02x", param.samplerate, param.bits, + param.channels, param.format)); + + if (wave_fd[0] == -1) { + return BX_SOUNDLOW_ERR; + } + if (param.bits == 16) { + if (signeddata == 1) { + fmt = AFMT_S16_LE; + } else { + fmt = AFMT_U16_LE; + } + } else if (param.bits == 8) { + if (signeddata == 1) { + fmt = AFMT_S8; + } else { + fmt = AFMT_U8; } } else { - if ((frequency == wave_ch[0].oldfreq) && - (bits == wave_ch[0].oldbits) && - (stereo == wave_ch[0].oldstereo) && - (format == wave_ch[0].oldformat)) - return BX_SOUNDLOW_OK; // nothing to do - } - wave_ch[0].oldfreq = frequency; - wave_ch[0].oldbits = bits; - wave_ch[0].oldstereo = stereo; - wave_ch[0].oldformat = format; - - if (bits == 16) - if (signeddata == 1) - fmt = AFMT_S16_LE; - else - fmt = AFMT_U16_LE; - else if (bits == 8) - if (signeddata == 1) - fmt = AFMT_S8; - else - fmt = AFMT_U8; - else return BX_SOUNDLOW_ERR; - - // set frequency etc. + } + // set frequency etc. ret = ioctl(wave_fd[0], SNDCTL_DSP_RESET); if (ret != 0) - BX_DEBUG(("ioctl(SNDCTL_DSP_RESET): %s", strerror(errno))); + BX_ERROR(("ioctl(SNDCTL_DSP_RESET): %s", strerror(errno))); /* ret = ioctl(wave_fd[0], SNDCTL_DSP_SETFRAGMENT, &fragment); @@ -168,22 +146,21 @@ int bx_sound_linux_c::startwaveplayback(int frequency, int bits, bx_bool stereo, */ ret = ioctl(wave_fd[0], SNDCTL_DSP_SETFMT, &fmt); - if (ret != 0) // abort if the format is unknown, to avoid playing noise - { - BX_DEBUG(("ioctl(SNDCTL_DSP_SETFMT, %d): %s", - fmt, strerror(errno))); - return BX_SOUNDLOW_ERR; + if (ret != 0) { // abort if the format is unknown, to avoid playing noise + BX_ERROR(("ioctl(SNDCTL_DSP_SETFMT, %d): %s", + fmt, strerror(errno))); + return BX_SOUNDLOW_ERR; } - ret = ioctl(wave_fd[0], SNDCTL_DSP_STEREO, &stereo); + ret = ioctl(wave_fd[0], SNDCTL_DSP_CHANNELS, &channels); if (ret != 0) - BX_DEBUG(("ioctl(SNDCTL_DSP_STEREO, %d): %s", - stereo, strerror(errno))); + BX_ERROR(("ioctl(SNDCTL_DSP_CHANNELS, %d): %s", + channels, strerror(errno))); ret = ioctl(wave_fd[0], SNDCTL_DSP_SPEED, &frequency); if (ret != 0) - BX_DEBUG(("ioctl(SNDCTL_DSP_SPEED, %d): %s", - frequency, strerror(errno))); + BX_ERROR(("ioctl(SNDCTL_DSP_SPEED, %d): %s", + frequency, strerror(errno))); // ioctl(wave_fd[0], SNDCTL_DSP_GETBLKSIZE, &fragment); // BX_DEBUG(("current output block size is %d", fragment)); @@ -197,10 +174,13 @@ int bx_sound_linux_c::sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *s Bit8u *tmpbuffer; if (memcmp(src_param, &emu_pcm_param, sizeof(bx_pcm_param_t)) != 0) { - startwaveplayback(src_param->samplerate, 16, 1, 1); emu_pcm_param = *src_param; cvt_mult = (src_param->bits == 8) ? 2 : 1; if (src_param->channels == 1) cvt_mult <<= 1; + if (src_param->samplerate != real_pcm_param.samplerate) { + real_pcm_param.samplerate = src_param->samplerate; + set_pcm_params(real_pcm_param); + } } if (wave_fd[0] == -1) { return BX_SOUNDLOW_ERR; @@ -218,27 +198,12 @@ int bx_sound_linux_c::sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *s } } -int bx_sound_linux_c::stopwaveplayback() -{ - // ioctl(wave_fd[0], SNDCTL_DSP_SYNC); - // close(wave_fd[0]); - // wave_fd[0] = -1; - - return BX_SOUNDLOW_OK; -} - int bx_sound_linux_c::closewaveoutput() { - if (wave_device[0] != NULL) - delete(wave_device[0]); - - if (wave_fd[0] != -1) - { - close(wave_fd[0]); - wave_fd[0] = -1; + if (wave_fd[0] != -1) { + close(wave_fd[0]); + wave_fd[0] = -1; } - wave_device[0] = NULL; - return BX_SOUNDLOW_OK; } @@ -249,18 +214,14 @@ int bx_sound_linux_c::openwaveinput(const char *wavedev, sound_record_handler_t record_timer_index = bx_pc_system.register_timer(this, record_timer_handler, 1, 1, 0, "soundlnx"); // record timer: inactive, continuous, frequency variable } - int length = strlen(wavedev) + 1; - - if (wave_device[1] != NULL) - delete [] wave_device[1]; - - wave_device[1] = new char[length]; - - if (wave_device[1] == NULL) - return BX_SOUNDLOW_ERR; - - strncpy(wave_device[1], wavedev, length); - + if (wave_fd[1] == -1) { + wave_fd[1] = open(wavedev, O_RDONLY); + if (wave_fd[1] == -1) { + return BX_SOUNDLOW_ERR; + } else { + BX_INFO(("OSS: opened input device %s", wavedev)); + } + } return BX_SOUNDLOW_OK; } @@ -281,16 +242,8 @@ int bx_sound_linux_c::startwaverecord(int frequency, int bits, bx_bool stereo, i timer_val = (Bit64u)record_packet_size * 1000000 / (frequency << shift); bx_pc_system.activate_timer(record_timer_index, (Bit32u)timer_val, 1); } - if ((wave_device[1] == NULL) || (strlen(wave_device[1]) < 1)) - return BX_SOUNDLOW_ERR; - if (wave_fd[1] == -1) { - wave_fd[1] = open(wave_device[1], O_RDONLY); - if (wave_fd[1] == -1) { - return BX_SOUNDLOW_ERR; - } else { - BX_INFO(("OSS: opened input device %s", wave_device[1])); - } + return BX_SOUNDLOW_ERR; } else { if ((frequency == wave_ch[0].oldfreq) && (bits == wave_ch[0].oldbits) && @@ -319,26 +272,26 @@ int bx_sound_linux_c::startwaverecord(int frequency, int bits, bx_bool stereo, i // set frequency etc. ret = ioctl(wave_fd[1], SNDCTL_DSP_RESET); if (ret != 0) - BX_DEBUG(("ioctl(SNDCTL_DSP_RESET): %s", strerror(errno))); + BX_ERROR(("ioctl(SNDCTL_DSP_RESET): %s", strerror(errno))); ret = ioctl(wave_fd[1], SNDCTL_DSP_SETFMT, &fmt); if (ret != 0) { // abort if the format is unknown, to avoid playing noise - BX_DEBUG(("ioctl(SNDCTL_DSP_SETFMT, %d): %s", + BX_ERROR(("ioctl(SNDCTL_DSP_SETFMT, %d): %s", fmt, strerror(errno))); return BX_SOUNDLOW_ERR; } ret = ioctl(wave_fd[1], SNDCTL_DSP_STEREO, &stereo); if (ret != 0) { - BX_DEBUG(("ioctl(SNDCTL_DSP_STEREO, %d): %s", - stereo, strerror(errno))); + BX_ERROR(("ioctl(SNDCTL_DSP_STEREO, %d): %s", + stereo, strerror(errno))); return BX_SOUNDLOW_ERR; } ret = ioctl(wave_fd[1], SNDCTL_DSP_SPEED, &frequency); if (ret != 0) { - BX_DEBUG(("ioctl(SNDCTL_DSP_SPEED, %d): %s", - frequency, strerror(errno))); + BX_ERROR(("ioctl(SNDCTL_DSP_SPEED, %d): %s", + frequency, strerror(errno))); return BX_SOUNDLOW_ERR; } @@ -370,16 +323,11 @@ int bx_sound_linux_c::stopwaverecord() int bx_sound_linux_c::closewaveinput() { stopwaverecord(); - if (wave_device[1] != NULL) - delete(wave_device[1]); - if (wave_fd[1] != -1) - { - close(wave_fd[1]); - wave_fd[1] = -1; + if (wave_fd[1] != -1) { + close(wave_fd[1]); + wave_fd[1] = -1; } - wave_device[1] = NULL; - return BX_SOUNDLOW_OK; } diff --git a/bochs/iodev/sound/soundlnx.h b/bochs/iodev/sound/soundlnx.h index 5888d480d..5e76eb3f7 100644 --- a/bochs/iodev/sound/soundlnx.h +++ b/bochs/iodev/sound/soundlnx.h @@ -32,17 +32,14 @@ public: virtual int get_type() {return BX_SOUNDLOW_LINUX;} - virtual int waveready(); - virtual int midiready(); - virtual int openmidioutput(const char *mididev); + virtual int midiready(); virtual int sendmidicommand(int delta, int command, int length, Bit8u data[]); virtual int closemidioutput(); virtual int openwaveoutput(const char *wavedev); - virtual int startwaveplayback(int frequency, int bits, bx_bool stereo, int format); + virtual int set_pcm_params(bx_pcm_param_t param); virtual int sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *src_param); - virtual int stopwaveplayback(); virtual int closewaveoutput(); virtual int openwaveinput(const char *wavedev, sound_record_handler_t rh); @@ -55,7 +52,6 @@ public: void record_timer(void); private: FILE *midi; - char *wave_device[2]; int wave_fd[2]; struct { int oldfreq, oldbits, oldformat; diff --git a/bochs/iodev/sound/soundlow.cc b/bochs/iodev/sound/soundlow.cc index e0e036197..f5937bb23 100644 --- a/bochs/iodev/sound/soundlow.cc +++ b/bochs/iodev/sound/soundlow.cc @@ -186,6 +186,14 @@ int bx_sound_lowlevel_c::closemidioutput() int bx_sound_lowlevel_c::openwaveoutput(const char *wavedev) { UNUSED(wavedev); + real_pcm_param = default_pcm_param; + set_pcm_params(real_pcm_param); + return BX_SOUNDLOW_OK; +} + +int bx_sound_lowlevel_c::set_pcm_params(bx_pcm_param_t param) +{ + UNUSED(param); return BX_SOUNDLOW_OK; } @@ -257,8 +265,11 @@ void bx_sound_lowlevel_c::convert_pcm_data(Bit8u *src, int srcsize, Bit8u *dst, int bx_sound_lowlevel_c::sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *src_param) { if (memcmp(src_param, &emu_pcm_param, sizeof(bx_pcm_param_t)) != 0) { - startwaveplayback(src_param->samplerate, 16, 1, 1); emu_pcm_param = *src_param; + if (src_param->samplerate != real_pcm_param.samplerate) { + real_pcm_param.samplerate = src_param->samplerate; + set_pcm_params(real_pcm_param); + } } UNUSED(length); UNUSED(data); diff --git a/bochs/iodev/sound/soundlow.h b/bochs/iodev/sound/soundlow.h index f7dea162b..07289d243 100644 --- a/bochs/iodev/sound/soundlow.h +++ b/bochs/iodev/sound/soundlow.h @@ -90,6 +90,8 @@ public: virtual int closemidioutput(); virtual int openwaveoutput(const char *wavedev); + virtual int set_pcm_params(bx_pcm_param_t param); + // TODO: remove startwaveplayback() virtual int startwaveplayback(int frequency, int bits, bx_bool stereo, int format); virtual int sendwavepacket(int length, Bit8u data[], bx_pcm_param_t *src_param); virtual int stopwaveplayback();