Fixed bug in capture stop. Only current header should be returned to
app. Make wave fragment size adjustable to guarantee better than 10 ms latency. Makes a difference for 8 kHz voice apps.
This commit is contained in:
parent
35645ca40c
commit
0c55534707
|
@ -375,7 +375,7 @@ static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format)
|
||||||
error:
|
error:
|
||||||
close(fd);
|
close(fd);
|
||||||
return WAVERR_BADFORMAT;
|
return WAVERR_BADFORMAT;
|
||||||
error2:
|
error2:
|
||||||
close(fd);
|
close(fd);
|
||||||
return MMSYSERR_ERROR;
|
return MMSYSERR_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1534,12 +1534,21 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
|
||||||
* let's try to fragment the above 64KB (256 * 2^8) */
|
* let's try to fragment the above 64KB (256 * 2^8) */
|
||||||
audio_fragment = 0x01000008;
|
audio_fragment = 0x01000008;
|
||||||
} else {
|
} else {
|
||||||
/* shockwave player uses only 4 1k-fragments at a rate of 22050 bytes/sec
|
/* A wave device must have a worst case latency of 10 ms so calculate
|
||||||
* thus leading to 46ms per fragment, and a turnaround time of 185ms
|
* the largest fragment size less than 10 ms long.
|
||||||
*/
|
*/
|
||||||
/* 16 fragments max, 2^10=1024 bytes per fragment */
|
int fsize = lpDesc->lpFormat->nAvgBytesPerSec / 100; /* 10 ms chunk */
|
||||||
audio_fragment = 0x000F000A;
|
int shift = 0;
|
||||||
|
while ((1 << shift) <= fsize)
|
||||||
|
shift++;
|
||||||
|
shift--;
|
||||||
|
audio_fragment = 0x00100000 + shift; /* 16 fragments of 2^shift */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("using %d %d byte fragments (%ld ms)\n", audio_fragment >> 16,
|
||||||
|
1 << (audio_fragment & 0xffff),
|
||||||
|
((1 << (audio_fragment & 0xffff)) * 1000) / lpDesc->lpFormat->nAvgBytesPerSec);
|
||||||
|
|
||||||
if (wwo->state != WINE_WS_CLOSED) return MMSYSERR_ALLOCATED;
|
if (wwo->state != WINE_WS_CLOSED) return MMSYSERR_ALLOCATED;
|
||||||
/* we want to be able to mmap() the device, which means it must be opened readable,
|
/* we want to be able to mmap() the device, which means it must be opened readable,
|
||||||
* otherwise mmap() will fail (at least under Linux) */
|
* otherwise mmap() will fail (at least under Linux) */
|
||||||
|
@ -2794,6 +2803,34 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WINE_WM_STOPPING:
|
case WINE_WM_STOPPING:
|
||||||
|
wwi->state = WINE_WS_STOPPED;
|
||||||
|
wwi->dwTotalRecorded = 0;
|
||||||
|
if (wwi->state != WINE_WS_STOPPED)
|
||||||
|
{
|
||||||
|
if (wwi->ossdev->bTriggerSupport)
|
||||||
|
{
|
||||||
|
/* stop the recording */
|
||||||
|
wwi->ossdev->bInputEnabled = FALSE;
|
||||||
|
enable = getEnables(wwi->ossdev);
|
||||||
|
if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
|
||||||
|
wwi->ossdev->bInputEnabled = FALSE;
|
||||||
|
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* return current buffer to app */
|
||||||
|
lpWaveHdr = wwi->lpQueuePtr;
|
||||||
|
if (lpWaveHdr)
|
||||||
|
{
|
||||||
|
LPWAVEHDR lpNext = lpWaveHdr->lpNext;
|
||||||
|
TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
|
||||||
|
lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
|
||||||
|
lpWaveHdr->dwFlags |= WHDR_DONE;
|
||||||
|
widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
|
||||||
|
wwi->lpQueuePtr = lpNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetEvent(ev);
|
||||||
|
break;
|
||||||
case WINE_WM_RESETTING:
|
case WINE_WM_RESETTING:
|
||||||
wwi->state = WINE_WS_STOPPED;
|
wwi->state = WINE_WS_STOPPED;
|
||||||
wwi->dwTotalRecorded = 0;
|
wwi->dwTotalRecorded = 0;
|
||||||
|
@ -2888,18 +2925,21 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
|
||||||
* to do hardware playback without hardware capture. */
|
* to do hardware playback without hardware capture. */
|
||||||
audio_fragment = wwi->ossdev->audio_fragment;
|
audio_fragment = wwi->ossdev->audio_fragment;
|
||||||
} else {
|
} else {
|
||||||
/* This is actually hand tuned to work so that my SB Live:
|
/* A wave device must have a worst case latency of 10 ms so calculate
|
||||||
* - does not skip
|
* the largest fragment size less than 10 ms long.
|
||||||
* - does not buffer too much
|
*/
|
||||||
* when sending with the Shoutcast winamp plugin
|
int fsize = lpDesc->lpFormat->nAvgBytesPerSec / 100; /* 10 ms chunk */
|
||||||
*/
|
int shift = 0;
|
||||||
/* 15 fragments max, 2^10 = 1024 bytes per fragment */
|
while ((1 << shift) <= fsize)
|
||||||
audio_fragment = 0x000F000A;
|
shift++;
|
||||||
|
shift--;
|
||||||
|
audio_fragment = 0x00100000 + shift; /* 16 fragments of 2^shift */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("using %d %d byte fragments\n", audio_fragment >> 16,
|
TRACE("using %d %d byte fragments (%ld ms)\n", audio_fragment >> 16,
|
||||||
1 << (audio_fragment & 0xffff));
|
1 << (audio_fragment & 0xffff),
|
||||||
|
((1 << (audio_fragment & 0xffff)) * 1000) / lpDesc->lpFormat->nAvgBytesPerSec);
|
||||||
|
|
||||||
ret = OSS_OpenDevice(wwi->ossdev, O_RDONLY, &audio_fragment,
|
ret = OSS_OpenDevice(wwi->ossdev, O_RDONLY, &audio_fragment,
|
||||||
1,
|
1,
|
||||||
|
|
Loading…
Reference in New Issue