ALSA / OSS sound modules: startwaveplayback() rewritten to set_pcm_params()
and some related cleanups. TODO: Replace startwaveplayback() completely.
This commit is contained in:
parent
d2a85e576f
commit
7dbb5185bf
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user