diff --git a/audio/oss.cpp b/audio/oss.cpp index eb9628c..9e077f3 100644 --- a/audio/oss.cpp +++ b/audio/oss.cpp @@ -3,12 +3,7 @@ #include #include -//OSS4 soundcard.h includes below SNDCTL defines, but OSS3 does not -//However, OSS4 soundcard.h does not reside in -//Therefore, attempt to manually define SNDCTL values if using OSS3 header -//Note that if the defines below fail to work on any specific platform, one can point soundcard.h -//above to the correct location for OSS4 (usually /usr/lib/oss/include/sys/soundcard.h) -//Failing that, one can disable OSS4 ioctl calls inside init() and remove the below defines +//OSSv4 features: define fallbacks for OSSv3 (where these ioctls are ignored) #ifndef SNDCTL_DSP_COOKEDMODE #define SNDCTL_DSP_COOKEDMODE _IOW('P', 30, int) @@ -31,12 +26,14 @@ struct AudioOSS : Audio { string device = "/dev/dsp"; bool synchronize = true; uint frequency = 48000; + uint latency = 60; } settings; auto cap(const string& name) -> bool { if(name == Audio::Device) return true; if(name == Audio::Synchronize) return true; if(name == Audio::Frequency) return true; + if(name == Audio::Latency) return true; return false; } @@ -44,6 +41,7 @@ struct AudioOSS : Audio { if(name == Audio::Device) return settings.device; if(name == Audio::Synchronize) return settings.synchronize; if(name == Audio::Frequency) return settings.frequency; + if(name == Audio::Latency) return settings.latency; return {}; } @@ -66,6 +64,12 @@ struct AudioOSS : Audio { return true; } + if(name == Audio::Latency && value.is()) { + settings.latency = value.get(); + if(device.fd >= 0) init(); + return true; + } + return false; } @@ -81,13 +85,11 @@ struct AudioOSS : Audio { device.fd = open(settings.device, O_WRONLY, O_NONBLOCK); if(device.fd < 0) return false; - #if 1 //SOUND_VERSION >= 0x040000 - //attempt to enable OSS4-specific features regardless of version - //OSS3 ioctl calls will silently fail, but sound will still work - int cooked = 1, policy = 4; //policy should be 0 - 10, lower = less latency, more CPU usage + int cooked = 1; ioctl(device.fd, SNDCTL_DSP_COOKEDMODE, &cooked); + //policy: 0 = minimum latency (higher CPU usage); 10 = maximum latency (lower CPU usage) + int policy = min(10, settings.latency / 20); //note: latency measurement isn't exact ioctl(device.fd, SNDCTL_DSP_POLICY, &policy); - #endif int frequency = settings.frequency; ioctl(device.fd, SNDCTL_DSP_CHANNELS, &device.channels); ioctl(device.fd, SNDCTL_DSP_SETFMT, &device.format);