* Use the older fragments API for setting the driver buffer size,

since it gives much more fine grained control.
* Use a smaller buffer on Haiku, this will give some slight clicks
  when something is going on (for example launching Firefox), but
  should be bearable. The reduced latency is otherwise quite nice
  and VLC works again which outweights the seldom clicks. Obviously
  the best is to find and fix scheduler problems, but in the
  meantime, this may be more helpful to people.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27382 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-09-08 14:07:06 +00:00
parent fc60ab16f5
commit 7e4c91ec88
@@ -35,7 +35,7 @@ OpenSoundDeviceEngine::OpenSoundDeviceEngine(oss_audioinfo *info)
CALLED(); CALLED();
fInitCheckStatus = B_NO_INIT; fInitCheckStatus = B_NO_INIT;
memcpy(&fAudioInfo, info, sizeof(oss_audioinfo)); memcpy(&fAudioInfo, info, sizeof(oss_audioinfo));
// XXX:REMOVEME // XXX:REMOVEME
// set default format // set default format
/* /*
@@ -96,37 +96,28 @@ status_t OpenSoundDeviceEngine::Open(int mode)
return EIO; return EIO;
} }
// set latency policy = fragment size and total driver buffer size // set driver buffer size by using the "fragments" API
// TODO: export this setting as a BParameter? // TODO: export this setting as a BParameter?
// NOTE stippi: 4 means 2048 bytes driver buffer in my tests on a C-Media // NOTE stippi: 2048 bytes driver buffer is long enough for playback on
// This latency is long enough for playback on BeOS. On Haiku, testing on // BeOS. On Haiku, testing on HD Audio hardware, it is too short. However,
// HD Audio hardware, it is too short. However, I seem to remember the // I seem to remember the HD Audio supports 32 bit sample width (while
// HD Audio supports 32 bit sample width (while C-Media supports "only" // C-Media supports "only" 16). If OSS uses the same 2048 bytes even for
// 16). If OSS uses the same 2048 bytes even for 32 bit/sample, then I // 32 bit/sample, then I could see how that would be asking for too much,
// could see how that would be asking for too much, since that would // since that would effectively half the latency.
// effectively half the latency.
#ifdef HAIKU_TARGET_PLATFORM_HAIKU #ifdef HAIKU_TARGET_PLATFORM_HAIKU
v = 5; uint32 bufferCount = 6;
uint32 bufferSize = 0x000b; // 1024 bytes
#else #else
v = 4; uint32 bufferCount = 4;
#endif uint32 bufferSize = 0x000a; // 512 bytes
if (ioctl(fFD, SNDCTL_DSP_POLICY, &v, sizeof(int)) < 0) {
if (errno != EIO && errno != EINVAL) {
fInitCheckStatus = errno;
Close();
return EIO;
}
// TODO: use this older API as fallback:
#if 0
// set fragments
v = 0x7fff0000 | 0x000b; // unlimited * 2048
if (ioctl(fFD, SNDCTL_DSP_SETFRAGMENT, &v, sizeof(int)) < 0) {
fInitCheckStatus = errno;
Close();
return EIO;
}
#endif #endif
v = (bufferCount << 16) | bufferSize;
if (ioctl(fFD, SNDCTL_DSP_SETFRAGMENT, &v, sizeof(int)) < 0) {
fInitCheckStatus = errno;
Close();
return EIO;
} }
fDriverBufferSize = 2048; fDriverBufferSize = 2048;
@@ -180,7 +171,7 @@ OpenSoundDeviceEngine::UpdateInfo()
if (fFD < 0) if (fFD < 0)
return ENODEV; return ENODEV;
if (ioctl(fFD, SNDCTL_ENGINEINFO, &fAudioInfo, sizeof(oss_audioinfo)) < 0) if (ioctl(fFD, SNDCTL_ENGINEINFO, &fAudioInfo, sizeof(oss_audioinfo)) < 0)
return errno; return errno;
@@ -216,7 +207,7 @@ int OpenSoundDeviceEngine::GetChannels(void)
int chans = -1; int chans = -1;
CALLED(); CALLED();
if (ioctl(fFD, SNDCTL_DSP_CHANNELS, &chans, sizeof(int)) < 0) { if (ioctl(fFD, SNDCTL_DSP_CHANNELS, &chans, sizeof(int)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_CHANNELS", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_CHANNELS", strerror(errno)));
return -1; return -1;
} }
@@ -227,7 +218,7 @@ status_t OpenSoundDeviceEngine::SetChannels(int chans)
{ {
CALLED(); CALLED();
if (ioctl(fFD, SNDCTL_DSP_CHANNELS, &chans, sizeof(int)) < 0) { if (ioctl(fFD, SNDCTL_DSP_CHANNELS, &chans, sizeof(int)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_CHANNELS", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_CHANNELS", strerror(errno)));
return EIO; return EIO;
} }
@@ -241,7 +232,7 @@ int OpenSoundDeviceEngine::GetFormat(void)
int fmt = -1; int fmt = -1;
CALLED(); CALLED();
if (ioctl(fFD, SNDCTL_DSP_GETFMTS, &fmt, sizeof(int)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETFMTS, &fmt, sizeof(int)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETFMTS", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETFMTS", strerror(errno)));
return -1; return -1;
} }
@@ -252,7 +243,7 @@ status_t OpenSoundDeviceEngine::SetFormat(int fmt)
{ {
CALLED(); CALLED();
if (ioctl(fFD, SNDCTL_DSP_SETFMT, &fmt, sizeof(int)) < 0) { if (ioctl(fFD, SNDCTL_DSP_SETFMT, &fmt, sizeof(int)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_SETFMT", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_SETFMT", strerror(errno)));
return EIO; return EIO;
} }
@@ -265,7 +256,7 @@ int OpenSoundDeviceEngine::GetSpeed(void)
int speed = -1; int speed = -1;
CALLED(); CALLED();
if (ioctl(fFD, SNDCTL_DSP_SPEED, &speed, sizeof(int)) < 0) { if (ioctl(fFD, SNDCTL_DSP_SPEED, &speed, sizeof(int)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_SPEED", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_SPEED", strerror(errno)));
return -1; return -1;
} }
@@ -276,7 +267,7 @@ status_t OpenSoundDeviceEngine::SetSpeed(int speed)
{ {
CALLED(); CALLED();
if (ioctl(fFD, SNDCTL_DSP_SPEED, &speed, sizeof(int)) < 0) { if (ioctl(fFD, SNDCTL_DSP_SPEED, &speed, sizeof(int)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_SPEED", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_SPEED", strerror(errno)));
return EIO; return EIO;
} }
@@ -295,7 +286,7 @@ size_t OpenSoundDeviceEngine::GetISpace(audio_buf_info *info)
if (!(fOpenMode & OPEN_READ)) if (!(fOpenMode & OPEN_READ))
return 0; return 0;
if (ioctl(fFD, SNDCTL_DSP_GETISPACE, info, sizeof(audio_buf_info)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETISPACE, info, sizeof(audio_buf_info)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETISPACE", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETISPACE", strerror(errno)));
return EIO; return EIO;
} }
@@ -314,7 +305,7 @@ size_t OpenSoundDeviceEngine::GetOSpace(audio_buf_info *info)
if (!(fOpenMode & OPEN_WRITE)) if (!(fOpenMode & OPEN_WRITE))
return 0; return 0;
if (ioctl(fFD, SNDCTL_DSP_GETOSPACE, info, sizeof(audio_buf_info)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETOSPACE, info, sizeof(audio_buf_info)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETOSPACE", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETOSPACE", strerror(errno)));
return EIO; return EIO;
} }
@@ -335,12 +326,12 @@ OpenSoundDeviceEngine::GetCurrentIPtr(int32 *fifoed, oss_count_t *info)
if (!(fOpenMode & OPEN_READ)) if (!(fOpenMode & OPEN_READ))
return 0; return 0;
if (ioctl(fFD, SNDCTL_DSP_CURRENT_IPTR, info, sizeof(oss_count_t)) < 0) { if (ioctl(fFD, SNDCTL_DSP_CURRENT_IPTR, info, sizeof(oss_count_t)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_CURRENT_IPTR", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_CURRENT_IPTR", strerror(errno)));
//return EIO; //return EIO;
// fallback: try GET*PTR // fallback: try GET*PTR
if (ioctl(fFD, SNDCTL_DSP_GETIPTR, &cinfo, sizeof(count_info)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETIPTR, &cinfo, sizeof(count_info)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETIPTR", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETIPTR", strerror(errno)));
return 0; return 0;
} }
@@ -371,7 +362,7 @@ OpenSoundDeviceEngine::GetCurrentOPtr(int32* fifoed, size_t* fragmentPos)
memset(&info, 0, sizeof(oss_count_t)); memset(&info, 0, sizeof(oss_count_t));
if (ioctl(fFD, SNDCTL_DSP_CURRENT_OPTR, &info, sizeof(oss_count_t)) < 0) { if (ioctl(fFD, SNDCTL_DSP_CURRENT_OPTR, &info, sizeof(oss_count_t)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_CURRENT_OPTR", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_CURRENT_OPTR", strerror(errno)));
return 0; return 0;
@@ -380,7 +371,7 @@ OpenSoundDeviceEngine::GetCurrentOPtr(int32* fifoed, size_t* fragmentPos)
if (fragmentPos != NULL) { if (fragmentPos != NULL) {
count_info cinfo; count_info cinfo;
if (ioctl(fFD, SNDCTL_DSP_GETOPTR, &cinfo, sizeof(count_info)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETOPTR, &cinfo, sizeof(count_info)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETOPTR", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETOPTR", strerror(errno)));
return 0; return 0;
} }
@@ -405,7 +396,7 @@ OpenSoundDeviceEngine::GetIOverruns()
if (!(fOpenMode & OPEN_WRITE)) if (!(fOpenMode & OPEN_WRITE))
return 0; return 0;
if (ioctl(fFD, SNDCTL_DSP_GETERROR, &info, sizeof(info)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETERROR, &info, sizeof(info)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETERROR", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETERROR", strerror(errno)));
return 0; return 0;
} }
@@ -423,7 +414,7 @@ OpenSoundDeviceEngine::GetOUnderruns()
if (!(fOpenMode & OPEN_WRITE)) if (!(fOpenMode & OPEN_WRITE))
return 0; return 0;
if (ioctl(fFD, SNDCTL_DSP_GETERROR, &info, sizeof(info)) < 0) { if (ioctl(fFD, SNDCTL_DSP_GETERROR, &info, sizeof(info)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GETERROR", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GETERROR", strerror(errno)));
return 0; return 0;
} }
@@ -446,12 +437,12 @@ status_t OpenSoundDeviceEngine::StartRecording(void)
group.id = 0; group.id = 0;
group.mode = PCM_ENABLE_INPUT; group.mode = PCM_ENABLE_INPUT;
if (ioctl(fFD, SNDCTL_DSP_SYNCGROUP, &group, sizeof(group)) < 0) { if (ioctl(fFD, SNDCTL_DSP_SYNCGROUP, &group, sizeof(group)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_SYNCGROUP", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_SYNCGROUP", strerror(errno)));
return EIO; return EIO;
} }
if (ioctl(fFD, SNDCTL_DSP_SYNCSTART, &group.id, sizeof(group.id)) < 0) { if (ioctl(fFD, SNDCTL_DSP_SYNCSTART, &group.id, sizeof(group.id)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_SYNCSTART", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_SYNCSTART", strerror(errno)));
return EIO; return EIO;
} }
@@ -546,14 +537,14 @@ status_t OpenSoundDeviceEngine::AcceptFormatFor(int fmt, media_format &format, b
err = WildcardFormatFor(fmt, wc); err = WildcardFormatFor(fmt, wc);
if (err < B_OK) if (err < B_OK)
return err; return err;
err = Open(rec ? OPEN_READ : OPEN_WRITE); err = Open(rec ? OPEN_READ : OPEN_WRITE);
if (err < B_OK) if (err < B_OK)
return err; return err;
if (format.type == B_MEDIA_RAW_AUDIO) { if (format.type == B_MEDIA_RAW_AUDIO) {
media_multi_audio_format &raw = format.u.raw_audio; media_multi_audio_format &raw = format.u.raw_audio;
// channel count // channel count
raw.channel_count = MAX((unsigned)(Info()->min_channels), MIN((unsigned)(Info()->max_channels), raw.channel_count)); raw.channel_count = MAX((unsigned)(Info()->min_channels), MIN((unsigned)(Info()->max_channels), raw.channel_count));
err = SetChannels(raw.channel_count); err = SetChannels(raw.channel_count);
@@ -586,10 +577,10 @@ status_t OpenSoundDeviceEngine::AcceptFormatFor(int fmt, media_format &format, b
Close(); Close();
return err; return err;
} }
// endianness // endianness
raw.byte_order = OpenSoundDevice::convert_oss_format_to_endian(afmt); raw.byte_order = OpenSoundDevice::convert_oss_format_to_endian(afmt);
// sample rate // sample rate
raw.frame_rate = OpenSoundDevice::select_oss_rate(Info(), raw.frame_rate); // measured in Hertz raw.frame_rate = OpenSoundDevice::select_oss_rate(Info(), raw.frame_rate); // measured in Hertz
//raw.frame_rate = OpenSoundDevice::convert_oss_rate_to_media_rate(Info()->max_rate); // measured in Hertz //raw.frame_rate = OpenSoundDevice::convert_oss_rate_to_media_rate(Info()->max_rate); // measured in Hertz
@@ -648,14 +639,14 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
err = WildcardFormatFor(fmt, wc); err = WildcardFormatFor(fmt, wc);
if (err < B_OK) if (err < B_OK)
return err; return err;
err = Open(rec ? OPEN_READ : OPEN_WRITE); err = Open(rec ? OPEN_READ : OPEN_WRITE);
if (err < B_OK) if (err < B_OK)
return err; return err;
if (format.type == B_MEDIA_RAW_AUDIO) { if (format.type == B_MEDIA_RAW_AUDIO) {
media_multi_audio_format &raw = format.u.raw_audio; media_multi_audio_format &raw = format.u.raw_audio;
PRINT(("%s:step1 fmt=0x%08x, raw.format=0x%08lx\n", __FUNCTION__, fmt, raw.format)); PRINT(("%s:step1 fmt=0x%08x, raw.format=0x%08lx\n", __FUNCTION__, fmt, raw.format));
// select the best as default // select the best as default
if (!raw.format) { if (!raw.format) {
@@ -686,7 +677,7 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
Close(); Close();
return err; return err;
} }
// endianness // endianness
if (!raw.byte_order) if (!raw.byte_order)
raw.byte_order = OpenSoundDevice::convert_oss_format_to_endian(afmt); raw.byte_order = OpenSoundDevice::convert_oss_format_to_endian(afmt);
@@ -694,7 +685,7 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
Close(); Close();
return B_MEDIA_BAD_FORMAT; return B_MEDIA_BAD_FORMAT;
} }
// channel count // channel count
if (raw.channel_count == 0) if (raw.channel_count == 0)
raw.channel_count = (unsigned)Info()->min_channels; raw.channel_count = (unsigned)Info()->min_channels;
@@ -716,7 +707,7 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
Close(); Close();
return err; return err;
} }
#if 0 #if 0
raw.buffer_size = DEFAULT_BUFFER_SIZE raw.buffer_size = DEFAULT_BUFFER_SIZE
* (raw.format & media_raw_audio_format::B_AUDIO_SIZE_MASK) * (raw.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
@@ -724,7 +715,7 @@ status_t OpenSoundDeviceEngine::SpecializeFormatFor(int fmt, media_format &forma
#endif #endif
audio_buf_info abinfo; audio_buf_info abinfo;
if (ioctl(fFD, rec?SNDCTL_DSP_GETISPACE:SNDCTL_DSP_GETOSPACE, &abinfo, sizeof(abinfo)) < 0) { if (ioctl(fFD, rec?SNDCTL_DSP_GETISPACE:SNDCTL_DSP_GETOSPACE, &abinfo, sizeof(abinfo)) < 0) {
PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n", PRINT(("OpenSoundDeviceEngine::%s: %s: %s\n",
__FUNCTION__, "SNDCTL_DSP_GET?SPACE", strerror(errno))); __FUNCTION__, "SNDCTL_DSP_GET?SPACE", strerror(errno)));
return -1; return -1;
} }