New version

This commit is contained in:
Morten Delenk 2016-09-03 17:58:53 +02:00
parent d078033472
commit e5695b2365
No known key found for this signature in database
GPG key ID: 3F818D0F65DCB490

View file

@ -3,12 +3,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/soundcard.h> #include <sys/soundcard.h>
//OSS4 soundcard.h includes below SNDCTL defines, but OSS3 does not //OSSv4 features: define fallbacks for OSSv3 (where these ioctls are ignored)
//However, OSS4 soundcard.h does not reside in <sys/>
//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
#ifndef SNDCTL_DSP_COOKEDMODE #ifndef SNDCTL_DSP_COOKEDMODE
#define SNDCTL_DSP_COOKEDMODE _IOW('P', 30, int) #define SNDCTL_DSP_COOKEDMODE _IOW('P', 30, int)
@ -31,12 +26,14 @@ struct AudioOSS : Audio {
string device = "/dev/dsp"; string device = "/dev/dsp";
bool synchronize = true; bool synchronize = true;
uint frequency = 48000; uint frequency = 48000;
uint latency = 60;
} settings; } settings;
auto cap(const string& name) -> bool { auto cap(const string& name) -> bool {
if(name == Audio::Device) return true; if(name == Audio::Device) return true;
if(name == Audio::Synchronize) return true; if(name == Audio::Synchronize) return true;
if(name == Audio::Frequency) return true; if(name == Audio::Frequency) return true;
if(name == Audio::Latency) return true;
return false; return false;
} }
@ -44,6 +41,7 @@ struct AudioOSS : Audio {
if(name == Audio::Device) return settings.device; if(name == Audio::Device) return settings.device;
if(name == Audio::Synchronize) return settings.synchronize; if(name == Audio::Synchronize) return settings.synchronize;
if(name == Audio::Frequency) return settings.frequency; if(name == Audio::Frequency) return settings.frequency;
if(name == Audio::Latency) return settings.latency;
return {}; return {};
} }
@ -66,6 +64,12 @@ struct AudioOSS : Audio {
return true; return true;
} }
if(name == Audio::Latency && value.is<uint>()) {
settings.latency = value.get<uint>();
if(device.fd >= 0) init();
return true;
}
return false; return false;
} }
@ -81,13 +85,11 @@ struct AudioOSS : Audio {
device.fd = open(settings.device, O_WRONLY, O_NONBLOCK); device.fd = open(settings.device, O_WRONLY, O_NONBLOCK);
if(device.fd < 0) return false; if(device.fd < 0) return false;
#if 1 //SOUND_VERSION >= 0x040000 int cooked = 1;
//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
ioctl(device.fd, SNDCTL_DSP_COOKEDMODE, &cooked); 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); ioctl(device.fd, SNDCTL_DSP_POLICY, &policy);
#endif
int frequency = settings.frequency; int frequency = settings.frequency;
ioctl(device.fd, SNDCTL_DSP_CHANNELS, &device.channels); ioctl(device.fd, SNDCTL_DSP_CHANNELS, &device.channels);
ioctl(device.fd, SNDCTL_DSP_SETFMT, &device.format); ioctl(device.fd, SNDCTL_DSP_SETFMT, &device.format);