Fixed recording format settings (16 bit was broken) and reentrancy

issues.
This commit is contained in:
Eric Pouech 2000-08-25 21:33:45 +00:00 committed by Alexandre Julliard
parent 125102f54b
commit c70082fb22
1 changed files with 60 additions and 46 deletions

View File

@ -663,8 +663,8 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
int format; int format;
int sample_rate; int sample_rate;
int dsp_stereo; int dsp_stereo;
int audio_fragment;
int fragment_size; int fragment_size;
int audio_fragment;
WINE_WAVEOUT* wwo; WINE_WAVEOUT* wwo;
TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags); TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
@ -696,14 +696,10 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
wwo = &WOutDev[wDevID]; wwo = &WOutDev[wDevID];
if (dwFlags & WAVE_DIRECTSOUND) { if ((dwFlags & WAVE_DIRECTSOUND) && !(wwo->caps.dwSupport & WAVECAPS_DIRECTSOUND))
if (!(wwo->caps.dwSupport & WAVECAPS_DIRECTSOUND)) /* not supported, ignore it */
/* not supported, ignore it */ dwFlags &= ~WAVE_DIRECTSOUND;
dwFlags &= ~WAVE_DIRECTSOUND;
}
wwo->unixdev = 0;
if (access(SOUND_DEV, 0) != 0) if (access(SOUND_DEV, 0) != 0)
return MMSYSERR_NOTENABLED; return MMSYSERR_NOTENABLED;
if (dwFlags & WAVE_DIRECTSOUND) if (dwFlags & WAVE_DIRECTSOUND)
@ -717,16 +713,18 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
return MMSYSERR_ALLOCATED; return MMSYSERR_ALLOCATED;
} }
wwo->unixdev = audio;
wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
memcpy(&wwo->waveDesc, lpDesc, sizeof(WAVEOPENDESC)); memcpy(&wwo->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
memcpy(&wwo->format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT)); memcpy(&wwo->format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
if (WOutDev[wDevID].format.wBitsPerSample == 0) { if (wwo->format.wBitsPerSample == 0) {
WOutDev[wDevID].format.wBitsPerSample = 8 * WARN("Resetting zeroed wBitsPerSample\n");
(WOutDev[wDevID].format.wf.nAvgBytesPerSec / wwo->format.wBitsPerSample = 8 *
WOutDev[wDevID].format.wf.nSamplesPerSec) / (wwo->format.wf.nAvgBytesPerSec /
WOutDev[wDevID].format.wf.nChannels; wwo->format.wf.nSamplesPerSec) /
wwo->format.wf.nChannels;
} }
if (dwFlags & WAVE_DIRECTSOUND) { if (dwFlags & WAVE_DIRECTSOUND) {
@ -763,8 +761,12 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
/* even if we set fragment size above, read it again, just in case */ /* even if we set fragment size above, read it again, just in case */
IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, fragment_size); IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, fragment_size);
if (fragment_size == -1) {
wwo->unixdev = audio; WARN("IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
close(audio);
wwo->unixdev = 0;
return MMSYSERR_NOTENABLED;
}
wwo->dwFragmentSize = fragment_size; wwo->dwFragmentSize = fragment_size;
if (!(dwFlags & WAVE_DIRECTSOUND)) { if (!(dwFlags & WAVE_DIRECTSOUND)) {
@ -1697,8 +1699,11 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
*/ */
static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags) static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
{ {
int audio, abuf_size, smplrate, samplesize, dsp_stereo; int audio;
LPWAVEFORMAT lpFormat; int fragment_size;
int sample_rate;
int format;
int dsp_stereo;
WINE_WAVEIN* wwi; WINE_WAVEIN* wwi;
TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags); TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
@ -1725,56 +1730,65 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
wwi = &WInDev[wDevID];
wwi->unixdev = 0;
if (access(SOUND_DEV,0) != 0) return MMSYSERR_NOTENABLED; if (access(SOUND_DEV,0) != 0) return MMSYSERR_NOTENABLED;
audio = open(SOUND_DEV, O_RDONLY|O_NDELAY, 0); audio = open(SOUND_DEV, O_RDONLY|O_NDELAY, 0);
if (audio == -1) { if (audio == -1) {
WARN("can't open (%s)!\n", strerror(errno)); WARN("can't open (%s)!\n", strerror(errno));
return MMSYSERR_ALLOCATED; return MMSYSERR_ALLOCATED;
} }
IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
if (abuf_size < 1024 || abuf_size > 65536) {
if (abuf_size == -1)
{
WARN("IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
close(audio);
return MMSYSERR_NOTENABLED;
}
WARN("SNDCTL_DSP_GETBLKSIZE Invalid dwFragmentSize %d!\n",abuf_size);
}
wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
wwi = &WInDev[wDevID];
if (wwi->lpQueuePtr) { if (wwi->lpQueuePtr) {
WARN("Should have an empty queue (%p)\n", wwi->lpQueuePtr); WARN("Should have an empty queue (%p)\n", wwi->lpQueuePtr);
wwi->lpQueuePtr = NULL; wwi->lpQueuePtr = NULL;
} }
wwi->unixdev = audio; wwi->unixdev = audio;
wwi->dwFragmentSize = abuf_size;
wwi->dwTotalRecorded = 0; wwi->dwTotalRecorded = 0;
memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC)); wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
lpFormat = (LPWAVEFORMAT) lpDesc->lpFormat;
memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
memcpy(&wwi->format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
memcpy(&wwi->format, lpFormat, sizeof(PCMWAVEFORMAT));
wwi->format.wBitsPerSample = 8; /* <-------------- */
if (wwi->format.wf.nChannels == 0) return WAVERR_BADFORMAT;
if (wwi->format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
if (wwi->format.wBitsPerSample == 0) { if (wwi->format.wBitsPerSample == 0) {
WARN("Resetting zeroed wBitsPerSample\n");
wwi->format.wBitsPerSample = 8 * wwi->format.wBitsPerSample = 8 *
(wwi->format.wf.nAvgBytesPerSec / (wwi->format.wf.nAvgBytesPerSec /
wwi->format.wf.nSamplesPerSec) / wwi->format.wf.nSamplesPerSec) /
wwi->format.wf.nChannels; wwi->format.wf.nChannels;
} }
samplesize = wwi->format.wBitsPerSample;
smplrate = wwi->format.wf.nSamplesPerSec; sample_rate = wwi->format.wf.nSamplesPerSec;
dsp_stereo = (wwi->format.wf.nChannels > 1) ? TRUE : FALSE; dsp_stereo = (wwi->format.wf.nChannels > 1) ? TRUE : FALSE;
IOCTL(audio, SNDCTL_DSP_SPEED, smplrate); format = (wwi->format.wBitsPerSample == 16) ? AFMT_S16_LE : AFMT_U8;
IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
IOCTL(audio, SNDCTL_DSP_SETFMT, format);
IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo); IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
TRACE("wBitsPerSample=%u !\n", wwi->format.wBitsPerSample); IOCTL(audio, SNDCTL_DSP_SPEED, sample_rate);
TRACE("nSamplesPerSec=%lu !\n", wwi->format.wf.nSamplesPerSec);
TRACE("nChannels=%u !\n", wwi->format.wf.nChannels); /* paranoid checks */
TRACE("nAvgBytesPerSec=%lu\n", wwi->format.wf.nAvgBytesPerSec); if (format != ((wwi->format.wBitsPerSample == 16) ? AFMT_S16_LE : AFMT_U8))
ERR("Can't set format to %d (%d)\n",
(wwi->format.wBitsPerSample == 16) ? AFMT_S16_LE : AFMT_U8, format);
if (dsp_stereo != (wwi->format.wf.nChannels > 1) ? 1 : 0)
ERR("Can't set stereo to %u (%d)\n",
(wwi->format.wf.nChannels > 1) ? 1 : 0, dsp_stereo);
if (!NEAR_MATCH(sample_rate, wwi->format.wf.nSamplesPerSec))
ERR("Can't set sample_rate to %lu (%d)\n",
wwi->format.wf.nSamplesPerSec, sample_rate);
IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, fragment_size);
if (fragment_size == -1) {
WARN("IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
close(audio);
wwi->unixdev = 0;
return MMSYSERR_NOTENABLED;
}
wwi->dwFragmentSize = fragment_size;
TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n",
wwi->format.wBitsPerSample, wwi->format.wf.nAvgBytesPerSec,
wwi->format.wf.nSamplesPerSec, wwi->format.wf.nChannels,
wwi->format.wf.nBlockAlign);
wwi->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); wwi->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
wwi->hThread = CreateThread(NULL, 0, widRecorder, (LPVOID)(DWORD)wDevID, 0, &(wwi->dwThreadID)); wwi->hThread = CreateThread(NULL, 0, widRecorder, (LPVOID)(DWORD)wDevID, 0, &(wwi->dwThreadID));