ALSA / OSS sound modules: startwaveplayback() rewritten to set_pcm_params()

and some related cleanups.
TODO: Replace startwaveplayback() completely.
This commit is contained in:
Volker Ruppert 2015-01-31 10:48:22 +00:00
parent d2a85e576f
commit 7dbb5185bf
6 changed files with 96 additions and 142 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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();