Return MMSYS_NOERROR even if we don't open the device with the

requested format, otherwise OSS_OpenDevice will not increment
open_count.
Use -1 to signal OSS_RawOpenDevice not to do ioctls because 0 is
ambiguous (also means mono as opposed to stereo).
This commit is contained in:
Francois Gouget 2003-01-16 00:19:04 +00:00 committed by Alexandre Julliard
parent 37bbb1c26e
commit 2147b9f5da
1 changed files with 33 additions and 28 deletions

View File

@ -152,9 +152,9 @@ typedef struct tagOSS_DEVICE {
unsigned open_access; unsigned open_access;
int fd; int fd;
DWORD owner_tid; DWORD owner_tid;
unsigned sample_rate; int sample_rate;
unsigned stereo; int stereo;
unsigned format; int format;
unsigned audio_fragment; unsigned audio_fragment;
BOOL full_duplex; BOOL full_duplex;
BOOL bTriggerSupport; BOOL bTriggerSupport;
@ -240,7 +240,7 @@ static const char *wodPlayerCmdString[] = {
*/ */
static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format) static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format)
{ {
int fd, val, err; int fd, val, rc;
if ((fd = open(ossdev->dev_name, ossdev->open_access|O_NDELAY, 0)) == -1) if ((fd = open(ossdev->dev_name, ossdev->open_access|O_NDELAY, 0)) == -1)
{ {
@ -258,46 +258,42 @@ static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format)
} }
/* First size and stereo then samplerate */ /* First size and stereo then samplerate */
err=MMSYSERR_NOERROR; if (ossdev->format>=0)
if (ossdev->format)
{ {
val = ossdev->format; val = ossdev->format;
ioctl(fd, SNDCTL_DSP_SETFMT, &ossdev->format); rc = ioctl(fd, SNDCTL_DSP_SETFMT, &ossdev->format);
if (val != ossdev->format) { if (rc != 0 || val != ossdev->format) {
TRACE("Can't set format to %d (returned %d)\n", val, ossdev->format); TRACE("Can't set format to %d (returned %d)\n", val, ossdev->format);
err=WAVERR_BADFORMAT;
if (strict_format) if (strict_format)
goto error; goto error;
} }
} }
if (ossdev->stereo) if (ossdev->stereo>=0)
{ {
val = ossdev->stereo; val = ossdev->stereo;
ioctl(fd, SNDCTL_DSP_STEREO, &ossdev->stereo); rc = ioctl(fd, SNDCTL_DSP_STEREO, &ossdev->stereo);
if (val != ossdev->stereo) { if (rc != 0 || val != ossdev->stereo) {
TRACE("Can't set stereo to %u (returned %d)\n", val, ossdev->stereo); TRACE("Can't set stereo to %u (returned %d)\n", val, ossdev->stereo);
err=WAVERR_BADFORMAT;
if (strict_format) if (strict_format)
goto error; goto error;
} }
} }
if (ossdev->sample_rate) if (ossdev->sample_rate>=0)
{ {
val = ossdev->sample_rate; val = ossdev->sample_rate;
ioctl(fd, SNDCTL_DSP_SPEED, &ossdev->sample_rate); rc = ioctl(fd, SNDCTL_DSP_SPEED, &ossdev->sample_rate);
if (!NEAR_MATCH(val, ossdev->sample_rate)) { if (rc != 0 || !NEAR_MATCH(val, ossdev->sample_rate)) {
TRACE("Can't set sample_rate to %u (returned %d)\n", val, ossdev->sample_rate); TRACE("Can't set sample_rate to %u (returned %d)\n", val, ossdev->sample_rate);
err=WAVERR_BADFORMAT;
if (strict_format) if (strict_format)
goto error; goto error;
} }
} }
ossdev->fd = fd; ossdev->fd = fd;
return err; return MMSYSERR_NOERROR;
error: error:
close(fd); close(fd);
return err; return WAVERR_BADFORMAT;
} }
/****************************************************************** /******************************************************************
@ -428,7 +424,7 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
int rc,arg; int rc,arg;
int f,c,r; int f,c,r;
if (OSS_OpenDevice(ossdev, O_WRONLY, NULL, 0, 0, 0, 0) != 0) return FALSE; if (OSS_OpenDevice(ossdev, O_WRONLY, NULL, 0,-1,-1,-1) != 0) return FALSE;
ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0); ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
/* FIXME: some programs compare this string against the content of the /* FIXME: some programs compare this string against the content of the
@ -471,14 +467,19 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
for (f=0;f<2;f++) { for (f=0;f<2;f++) {
arg=win_std_oss_fmts[f]; arg=win_std_oss_fmts[f];
rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg); rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg);
if (rc!=0 || arg!=win_std_oss_fmts[f]) if (rc!=0 || arg!=win_std_oss_fmts[f]) {
TRACE("DSP_SAMPLESIZE: rc=%d returned 0x%x for 0x%x\n",
rc,arg,win_std_oss_fmts[f]);
continue; continue;
}
for (c=0;c<2;c++) { for (c=0;c<2;c++) {
arg=c; arg=c;
rc=ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &arg); rc=ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &arg);
if (rc!=0 || arg!=c) if (rc!=0 || arg!=c) {
TRACE("DSP_STEREO: rc=%d returned %d for %d\n",rc,arg,c);
continue; continue;
}
if (c==1) { if (c==1) {
ossdev->out_caps.wChannels=2; ossdev->out_caps.wChannels=2;
ossdev->out_caps.dwSupport|=WAVECAPS_LRVOLUME; ossdev->out_caps.dwSupport|=WAVECAPS_LRVOLUME;
@ -521,7 +522,7 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
int rc,arg; int rc,arg;
int f,c,r; int f,c,r;
if (OSS_OpenDevice(ossdev, O_RDONLY, NULL, 0, 0, 0, 0) != 0) return FALSE; if (OSS_OpenDevice(ossdev, O_RDONLY, NULL, 0,-1,-1,-1) != 0) return FALSE;
ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0); ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
/* See comment in OSS_WaveOutInit */ /* See comment in OSS_WaveOutInit */
@ -553,14 +554,19 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
for (f=0;f<2;f++) { for (f=0;f<2;f++) {
arg=win_std_oss_fmts[f]; arg=win_std_oss_fmts[f];
rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg); rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg);
if (rc!=0 || arg!=win_std_oss_fmts[f]) if (rc!=0 || arg!=win_std_oss_fmts[f]) {
TRACE("DSP_SAMPLESIZE: rc=%d returned 0x%x for 0x%x\n",
rc,arg,win_std_oss_fmts[f]);
continue; continue;
}
for (c=0;c<2;c++) { for (c=0;c<2;c++) {
arg=c; arg=c;
rc=ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &arg); rc=ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &arg);
if (rc!=0 || arg!=c) if (rc!=0 || arg!=c) {
TRACE("DSP_STEREO: rc=%d returned %d for %d\n",rc,arg,c);
continue; continue;
}
if (c==1) { if (c==1) {
ossdev->in_caps.wChannels=2; ossdev->in_caps.wChannels=2;
} }
@ -594,7 +600,7 @@ static void OSS_WaveFullDuplexInit(OSS_DEVICE* ossdev)
{ {
int caps; int caps;
if (OSS_OpenDevice(ossdev, O_RDWR, NULL, 0, 0, 0, 0) != 0) return; if (OSS_OpenDevice(ossdev, O_RDWR, NULL, 0,-1,-1,-1) != 0) return;
if (ioctl(ossdev->fd, SNDCTL_DSP_GETCAPS, &caps) == 0) if (ioctl(ossdev->fd, SNDCTL_DSP_GETCAPS, &caps) == 0)
{ {
ossdev->full_duplex = (caps & DSP_CAP_DUPLEX); ossdev->full_duplex = (caps & DSP_CAP_DUPLEX);
@ -1322,13 +1328,12 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
(lpDesc->lpFormat->nChannels > 1) ? 1 : 0, (lpDesc->lpFormat->nChannels > 1) ? 1 : 0,
(lpDesc->lpFormat->wBitsPerSample == 16) (lpDesc->lpFormat->wBitsPerSample == 16)
? AFMT_S16_LE : AFMT_U8); ? AFMT_S16_LE : AFMT_U8);
if ((ret==WAVERR_BADFORMAT) && (dwFlags & WAVE_DIRECTSOUND)) { if ((ret==MMSYSERR_NOERROR) && (dwFlags & WAVE_DIRECTSOUND)) {
lpDesc->lpFormat->nSamplesPerSec=wwo->ossdev->sample_rate; lpDesc->lpFormat->nSamplesPerSec=wwo->ossdev->sample_rate;
lpDesc->lpFormat->nChannels=(wwo->ossdev->stereo ? 2 : 1); lpDesc->lpFormat->nChannels=(wwo->ossdev->stereo ? 2 : 1);
lpDesc->lpFormat->wBitsPerSample=(wwo->ossdev->format == AFMT_U8 ? 8 : 16); lpDesc->lpFormat->wBitsPerSample=(wwo->ossdev->format == AFMT_U8 ? 8 : 16);
lpDesc->lpFormat->nBlockAlign=lpDesc->lpFormat->nChannels*lpDesc->lpFormat->wBitsPerSample/8; lpDesc->lpFormat->nBlockAlign=lpDesc->lpFormat->nChannels*lpDesc->lpFormat->wBitsPerSample/8;
lpDesc->lpFormat->nAvgBytesPerSec=lpDesc->lpFormat->nSamplesPerSec*lpDesc->lpFormat->nBlockAlign; lpDesc->lpFormat->nAvgBytesPerSec=lpDesc->lpFormat->nSamplesPerSec*lpDesc->lpFormat->nBlockAlign;
ret=MMSYSERR_NOERROR;
TRACE("OSS_OpenDevice returned this format: %ldx%dx%d\n", TRACE("OSS_OpenDevice returned this format: %ldx%dx%d\n",
lpDesc->lpFormat->nSamplesPerSec, lpDesc->lpFormat->nSamplesPerSec,
lpDesc->lpFormat->wBitsPerSample, lpDesc->lpFormat->wBitsPerSample,